I want to create unique binary lists from the elements in this list.
for example;
`["Jack", "John", "Ally"] ---> ["Jack", "John"], ["Jack", "Ally"], ["John", "Ally]`
["Jack", "John", "Ally", "Emmy"] --->
["Jack", "John"], ["Jack", "Ally"], ["Jack", "Emmy"],
["John", "Ally"], ["John", "Emmy"],
["Ally", "Emmy"]`
but the same values will not repeat. then i want to save these binary lists in database.
`var data = new Names() {
Name1 = "Jack",
Name2 = "John"
};
dbContext.Names.Add(data);`
how can I do that?
you can run two for loops..
List<string> names = new List<string> { "Jack", "John", "Ally", "Emmy" };
List<List<string>> ls = new List<List<string>>();
for (int i = 0; i < names.Count; i++)
{
for (int j = i + 1; j < names.Count; j++)
{
ls.Add(new List<string> { names[i], names[j] });
}
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm making a program to automate rolling initiative. I have most of it done, but I can't sort the outputs because it's a jagged array. I need the second column of each array in my jagged array to be sorted from highest to lowest.
using System;
using System.Linq;
namespace Auto_Initiative
{
class Program
{
static void Main(string[] args)
{
string[] encounter =
{
"Wizard", "18", "-2",
"Bard", "9", "3",
"Goblin 1", "16", "1",
"Goblin 2", "14", "1"
};
int[][] numbers = new int[encounter.Length / 3][];
int loop = 0;
for(int i = 0; i > encounter.Length; i += 3)
{
// Name number, real roll
numbers[loop] = new int[2] {i, Int32.Parse(encounter[i + 1]) + Int32.Parse(encounter[i + 2])};
}
Console.ReadKey();
}
}
}
One part of designing your software is choosing the right data structure for how you are planning to use it. Sometimes redundant data is required but we don't know what you are requirements are to make that decision. So as was mentioned by Sergey you should consider creating a custom class which I have shown an example of below. Also note that a string[] is not really a jagged array. By definition a jagged array has nested arrays of variable size. The data structure depicted above could be put in a regular string[][] and would not be jagged.
Object Oriented in Action
What you are looking for is stored in unitsSortedBySecondColumn.
class so65865986
{
static void Main(string[] args)
{
Encounter encounter = new Encounter
{
Units = new List<EncounterUnit> {
new EncounterUnit{
Name = "Wizard",
Column1 = 18,
Column2 = -2,
},
new EncounterUnit{
Name = "Bard",
Column1 = 9,
Column2 = 3,
},
new EncounterUnit{
Name = "Goblin 1",
Column1 = 16,
Column2 = 1,
},
new EncounterUnit{
Name = "Goblin 2",
Column1 = 14,
Column2 = 1,
},
},
};
var unitsSortedBySecondColumn = encounter.Units
.OrderBy(u => u.Column1)
.Select(u => new int[] { u.Column1, u.Column2 })
.ToArray();
}
}
class EncounterUnit
{
public string Name;
public int Column1; //Change name to whatever it means
public int Column2; //Change name to whatever it means
}
class Encounter
{
public List<EncounterUnit> Units;
}
Nested (but not Jagged) Array
class so65865986_nested_array
{
static void Main(string[] args)
{
string[][] encounter =
{
new string[] {"Wizard", "18", "-2" },
new string[] {"Bard", "9", "3" },
new string[] {"Goblin 1", "16", "1" },
new string[] {"Goblin 2", "14", "1" },
};
int[][] numbers = encounter
.Select(u => new int[] { int.Parse(u[1]), int.Parse(u[2]) })
.OrderBy(u => u[0])
.ToArray();
Console.ReadKey();
}
}
Other Notes
Also, another note. You don't need to use Int32 because it is recommended you use the aliases provided which in this case is int.
use this code:
string[] encounter =
{
"Wizard", "18", "-2",
"Bard", "9", "3",
"Goblin 1", "16", "1",
"Goblin 2", "14", "1"
};
int[,] numbers = new int[encounter.Length / 3, 3];
for (int i = 1; i < encounter.Length / 4; i++)
{
for (int j = 0; j < encounter.Length / 3; j += 1)
{
numbers[j, i] = Convert.ToInt32(encounter[i + (j * 3)]);
Console.Write(numbers[j, i] + " ");
}
Console.WriteLine(Environment.NewLine);
}
Console.ReadLine();
I am new to programming.
Let say i have
arr1 = {1, 2, 3, 4, 5}
arr2 = {+, - , *, /, =}
How can i display this two array in sequence by using two for loop in the form like this.
1+2-3*4/5=
A bit strange question but here you go...
string Result = string.Empty;
for (int i=0; i < arr1.Length; i++)
{
for (int j=i; j == i; j++)
{
Result += arr1[i]+arr2[j];
}
}
Console.Write(Result);
Why would you need 2 for loops for this task?
string[] arr1 = {"1", "2", "3", "4", "5"};
string[] arr2 = {"+", "-", "*", "/", "="};
for (int i = 0; i < arr1.Length; i++)
{
Console.Write(arr1[i]);
Console.Write(arr2[i]);
}
This - of course - assumes, that arr1 and arr2have the same length (number of elements).
EDIT
To display the result in a textbox you will require a variable:
string[] arr1 = {"1", "2", "3", "4", "5"};
string[] arr2 = {"+", "-", "*", "/", "="};
string result = "";
for (int i = 0; i < arr1.Length; i++)
result += arr1[i] + arr2[i]; // TxtDisplay.AppendText(arr1[i] + arr2[i])
TxtDisplay.Text = result;
This is tricky, but take a look at this :-)
var arr1 = new[] {1, 2, 3, 4, 5};
var arr2 = new[] {'+', '-', '*', '/', '='};
for (int i = 0; i < Math.Min(arr1.Length, arr2.Length); i++)
Console.Write("{0}{1}", arr1[i], arr2[i]);
for (; false;) ;//second loop, as you wish
In production code, during optimization phase, you can remove second loop.
var arr1 = new[] {1, 2, 3, 4, 5};
var arr2 = new[] {"+", "-", "*", "/", "="};
for (int i = 0; i < arr1.Length;i++)
{
Console.Write(arr1[i]);
for (;i<arr2.Length;)
{
Console.Write(arr2[i]);
break;
}
}
produces
1+2-3*4/5=
Koby is right, but you could do it slightly faster in this particular case. Since the arrays are the same size, you need one less loop. Of course, if the arrays are of different lengths then this will not work properly.
string Result = string.Empty;
for (int i=0; i < arr1.Length; i++)
Result += arr1[i]+arr2[i];
Console.WriteLine(Result);
Use the LINQ extensions Enumerable.Zip and Enumerable.Aggregate for that
var combined = arr1.Zip( arr2, (a1, a2) => a1+a2 );
var result = combined.Aggregate( (agg, item ) => agg + item );
// Display result whereever you like
Console.WriteLine( result );
I add items from an array into a ListView like below:
for (int i = 0; i < dataKeyList.Count; i++)
{
CallTabLv.Items.Add(new { Label = " " + keyArray[i], Value = valueArray[i] });
}
If the keyArray[i] contains an item called CustomerName, how can I move it and its value to the top of the list ?
Edit:
Let say:
string[] arr1 = new string[] { "one", "two", "three" };
string[] arr2 = new string[] { "1", "2", "3" };
for (int i = 0; i < arr1.Length; i++)
{
listView.Items.Add(new { C1 = arr1[i], C2 = arr2[i] });
}
Output:
Col Col2
-----------
one 1
two 2
three 3
I want to move "three 3" to the top of the list, so it would be like:
Col Col2
-----------
three 3
two 2
one 1
Any suggestions?
Instead of adding item, You can use [Items.Insert][1] to insert an item in particular position,It can be used To Change position of an existing item in nth index.
ListViewItem item= new ListViewItem("Test");//Define item here;
if(!CallTabLv.Items.Contains(theItem))
{
CallTabLv.Items.Insert(0,item);
}
else
{
n = CallTabLv.Items.IndexOf(item);
CallTabLv.Items.RemoveAt(n);
CallTabLv.Items.Insert(0, item);
}
I have n number of lists of objects which I need to convert to a list of object arrays each containing a unique combination of objects from the original lists.
Example:
myList[0] = new List<object>(){a, b, c, d};
myList[1] = new List<object>(){"0", "1", "2", "3", "4"};
myList[2] = new List<object>(){0, 1, 2};
myList[3] = new List<object>(){aClass, bClass}
etc.
Needs to become:
newList[0] = new object[]{a, "0", 0, aClass};
newList[1] = new object[]{a, "0", 0, bClass};
newList[2] = new object[]{a, "0", 1, aClass};
newList[3] = new object[]{a, "0", 1, bClass};
newList[4] = new object[]{a, "0", 2, aClass};
newList[5] = new object[]{a, "0", 2, bClass};
newList[6] = new object[]{a, "1", 0, aClass};
newList[7] = new object[]{a, "1", 0, bClass};
newList[8] = new object[]{a, "1", 1, aClass};
newList[9] = new object[]{a, "1", 1, bClass};
newList[10] = new object[]{a, "1", 2, aClass};
newList[11] = new object[]{a, "1", 2, bClass};
etc.
The order of the variables has to be preserved (the list at myList[0] has to be first, etc) because these object arrays are the parameters passed via reflection:
Indicator temp = (Indicator) newIndicator.Invoke(this, newList[i]);
If the number of lists of objects were static, it might look something like the following:
List<object[]> newList = new List<object[]>();
for(int i = 0; i < myList[0].Count; i++)
{
for(int i2 = 0; i2 < myList[1].Count; i2++)
{
for(int i3 = 0; i3 < myList[2].Count; i3++)
{
for(int i4 = 0; i4 < myList[3].Count; i4++)
{
object[] temp = new object[]{myList[0][i], myList[1][i2], myList[2][i3], myList[3][i4]};
newList.Add(temp);
}
}
}
}
My latest attempt was to create a list of indicies which held the current index of each list and incremented it appropriately, but my math doesn't seem to work out as I scale it out.
private List<object[]> ToParametersList(List<List<object>> listOfLists)
{
int counter = 1;
foreach(List<object> list in listOfLists){ counter *= list.Count; }
List<object[]> returnList = new List<object[]>();
List<int> indicies = new List<int>();
int tempSplit = 0;
List<int> splits = new List<int>();
List<int> splitcounters = new List<int>();
for(int i = 0; i < listOfLists.Count; i++)
{
if(i == 0 && listOfLists[0].Count > 2)
{
splits.Add(counter / listOfLists[0].Count);
tempSplit = counter / listOfLists[0].Count;
} else if(i > 0 && listOfLists[i].Count > 2) {
splits.Add(tempSplit / listOfLists[i].Count);
tempSplit /= listOfLists[i].Count;
} else if(listOfLists[i].Count == 2)
{
splits.Add(1);
}
indicies.Add(0);
splitcounters.Add(1);
}
for(int i = 0; i < counter; i++)
{
object[] newObject = new object[listOfLists.Count];
for(int i2 = 0; i2 < listOfLists.Count; i2++)
{
if(i < splits[i2] * splitcounters[i2] && ((indicies[i2] < listOfLists[i2].Count && listOfLists[i2].Count > 2) || indicies[i2] < listOfLists[i2].Count - 1))
{
newObject[i2] = listOfLists[i2][indicies[i2]];
}
else if(i >= splits[i2] * splitcounters[i2] && ((indicies[i2] < listOfLists[i2].Count && listOfLists[i2].Count > 2) || indicies[i2] < listOfLists[i2].Count - 1))
{
indicies[i2]++;
splitcounters[i2]++;
newObject[i2] = listOfLists[i2][indicies[i2]];
}
else
{
indicies[i2] = 0;
splitcounters[i2]++;
newObject[i2] = listOfLists[i2][indicies[i2]];
}
}
returnList.Add(newObject);
}
return returnList;
}
I have also gone through many of the recursion questions on here and am still having trouble understanding how to apply them to this particular situation (I am relatively new to recursion).
Any help would be greatly appreciated!
EDIT: In Cartesian products with n number of list the OP's post is confusing and the answer provided has no explanation of what is happening. The link to Eric Lippert's Blog is a general overview of Cartesian products which did not help me break the barrier that I needed to properly understand this in the context of what I was trying to do.
To be honest i did not read your last attempt. Other ways using Linq is great but if you really want a recursion follow this way.
To create a good recursion you need to look at which part of method varies and which part does not. the method should take parameters that varies for each call. Also you need if-else to end recursion somewhere.
List<object[]> newList = new List<object[]>();
for(int i = 0; i < myList[0].Count; i++)
{
for(int i2 = 0; i2 < myList[1].Count; i2++)
{
for(int i3 = 0; i3 < myList[2].Count; i3++)
{
for(int i4 = 0; i4 < myList[3].Count; i4++)
{
object[] temp = new object[]{myList[0][i], myList[1][i2], myList[2][i3], myList[3][i4]};
newList.Add(temp);
}
}
}
}
We want to use recursion in this method to be able to use it for any lenght of list.To do this you must convert loop into recursion call. but now you have unknown amount of loops.
The solution is to use params keyword. you can send any amount of int to method. this int's holds the variables i1, i2 , i3 , i4 .... just like the above method you have wrote.
The length of this array (params int[]) is exactly number of loops inside the normal method.
private static void Combine(List<List<object>> myList,List<object[]> newList,params int[] loopInd)
{
if (loopInd.Length <= myList.Count) // should not exceed number of loops.
{
int currentCount = myList[loopInd.Length - 1].Count;
while (loopInd[loopInd.Length - 1] < currentCount) // i<myList[0] , i2<myList[1] , i3<myList[2]
{
Combine(myList, newList, loopInd.Concat(new[] {0}).ToArray()); // Go for inner loop
loopInd[loopInd.Length - 1]++; // i++, i2++ , i3++ ...
}
}
else // no more loops.add the object[] into newList
{
int j = 0;
object[] temp = loopInd.Take(loopInd.Length - 1).Select(i => myList[j++][i]).ToArray();
newList.Add(temp);
}
}
The comments above shows the representations in normal method.
Then you can use it in this way.
List<List<object>> myList = new List<List<object>>();
myList.Add(new List<object>() { a, b, c, d });
myList.Add(new List<object>() { "0", "1", "2", "3", "4" });
myList.Add(new List<object>() { 0, 1, 2 });
myList.Add(new List<object>() {aClass, bClass});
List<object[]> newList = new List<object[]>();
Combine(myList, newList, 0);
// The newList is now what you want
Edit :
If you are after performance you can convert this Linq part
int j = 0;
object[] temp = loopInd.Take(loopInd.Length - 1).Select(i => myList[j++][i]).ToArray();
newList.Add(temp);
Into code
int j = 0;
object[] temp = new object[loopInd.Length - 1];
for (int i = 0; i < loopInd.Length - 1; i++,j++)
{
temp[i] = myList[j][loopInd[i]];
}
Here is a solution that accepts a number of lists that is unknown at compile time.
Method CombineArrayOfLists does what you need:
static List<List<object>> CombineArrayOfLists(List<object>[] myList)
{
List<List<object>> result = myList[0].Select(element => new List<object>() { element }).ToList();
for (int i = 1; i < myList.Length; i++)
{
result = (from c1 in result from c2 in myList[i] select new List<object>(c1) {c2}).ToList();
}
return result;
}
Note that you need to define the desired behavior in case any list in your array of lists is empty. To handle that case you may need to add an if statement to skip that list (if that is the appropriate thing to do).
A complete example written in a slightly more verbose form that could be easier to understand:
class Program
{
static void Main(string[] args)
{
List<object>[] myList = new List<object>[4];
AClass aClass = new AClass();
BClass bClass = new BClass();
myList[0] = new List<object>() { "a", "b", "c", "d" };
myList[1] = new List<object>() { "0", "1", "2", "3", "4" };
myList[2] = new List<object>() { 0, 1, 2 };
myList[3] = new List<object>() { aClass, bClass };
List<List<object>> result = CombineArrayOfLists(myList);
PrintList(result);
}
static List<List<object>> CombineArrayOfLists(List<object>[] myList)
{
List<List<object>> result = myList[0].Select(element => new List<object>() { element }).ToList();
for (int i = 1; i < myList.Length; i++)
{
result = CombineCollections(result, myList[i]).ToList();
}
return result;
}
private static IEnumerable<List<object>> CombineCollections(IEnumerable<List<object>> collection1, List<object> collection2)
{
return from c1 in collection1 from c2 in collection2 select new List<object>(c1) { c2 };
}
// A more verbose form of CombineCollections that may be easier to understand:
//private static IEnumerable<List<object>> CombineCollections(IEnumerable<List<object>> collection1, List<object> collection2)
//{
// foreach (List<object> c1 in collection1)
// {
// foreach (object c2 in collection2)
// {
// List<object> l1 = new List<object>(c1) { c2 };
// yield return l1;
// }
// }
//}
private static void PrintList(List<List<object>> collection)
{
collection.ForEach(list =>
{
list.ForEach(element =>
{
Console.Write(element);
Console.Write(" ");
});
Console.WriteLine();
});
}
}
public class AClass
{ }
public class BClass
{ }
You can use LINQ to get Cartesian product of list of objects.
List<object> arr1 = new List<object> { "a", "b", "c" };
List<object> arr2 = new List<object> { 3, 2, 4,5 };
List<object> arr3 = new List<object> { "0", "1", "2", "3", "4" };
var result = from x in arr1
from y in arr2
from z in arr3
select new { x = x, y = y,z=z };
List<object[]> newList = new List<object[]>();
foreach (var line in result)
{
newList.Add(new object[] { line.x, line.y, line.z });
}
foreach (var obj in newList)
{
foreach (var ele in obj)
{
Console.Write(ele.ToString() + " ");
}
Console.WriteLine();
}
Console.ReadKey();
This will provide you with the list of one objects in the way you require.
Here is the running example
http://csharppad.com/gist/45ebe7c9576dab9c00b8
I have two arrays say one is string array and the other is int array
string array has---> "11","11","11","11","12","12" elements and the int array has 1,2,3,4,5,6 respectively.
I want result two arrays containing string array--->"11","12"
and int array---->10,11
If the string array has duplicate elements, the other array containing that respective index value must be added .For example "11" is in 1st,2nd,3rd,4th index So its corresponding value must sum of all those elements in other array.Can it be done?
I have written some code but unable to do it..
static void Main(string[] args)
{
//var newchartValues = ["","","","","","",""];
//var newdates = dates.Split(',');
//string[] newchartarray = newchartValues;
//string[] newdatearray = newdates;
int[] newchartValues = new int[] { 1, 2, 3, 4, 5, 6 };
string[] newdates = new string[] { "11", "11","11","12","12","12" };
int[] intarray = new int[newchartValues.Length];
List<int> resultsumarray = new List<int>();
for (int i = 0; i < newchartValues.Length - 1; i++)
{
intarray[i] = Convert.ToInt32(newchartValues[i]);
}
for (int i = 0; i < newdates.Length; i++)
{
for (int j = 0; j < intarray.Length; j++)
{
if (newdates[i] == newdates[i + 1])
{
intarray[j] += intarray[j + 1];
resultsumarray.Add(intarray[j]);
}
}
resultsumarray.ToArray();
}
}
I don't quite get what you need, but I think I fixed your code, result will contain 10 and 11 in this example:
int[] newchartValues = new int[] { 1, 2, 3, 4, 5, 6 };
string[] newdates = new string[] { "11", "11", "11", "11", "12", "12" };
List<int> result = new List<int>();
if (newdates.Length == 0)
return;
string last = newdates[0];
int cursum = newchartValues[0];
for (var i = 1; i <= newdates.Length; i++)
{
if (i == newdates.Length || newdates[i] != last)
{
result.Add(cursum);
if (i == newdates.Length)
break;
last = newdates[i];
cursum = 0;
}
cursum += newchartValues[i];
}
Here is an approach that should do what you want:
List<int> resultsumarray = newdates
.Select((str, index) => new{ str, index })
.GroupBy(x => x.str)
.Select(xg => xg.Sum(x => newchartValues[x.index]))
.ToList();
Result is a List<int> with two number: 6, 15
Something like this?
int[] newchartValues = new int[] { 1, 2, 3, 4, 5, 6 };
int[] newdates = new int[] { 11, 11,11,12,12,12 };
var pairs = Enumerable.Zip(newdates, newchartValues, (x, y) => new { x, y })
.GroupBy(z => z.x)
.Select(g => new { k = g.Key, s = g.Sum(z => z.y) })
.ToList();
var distinctDates = pairs.Select(p => p.k).ToArray();
var sums = pairs.Select(p => p.s).ToArray();