groupping/sorting/splitting 2D list/array - c#

I have following 2D array
var array1 = new string[][]
{
new string[] {A,B,C},
new string[] {A,X,Y},
new string[] {D,L,K},
new string[] {A,X,W}
};
At the end I would like to sort or group this list and output I want to display on my MVC view on a table as below
A / X / Y,W
/ B/ C
D/ l / K
I dont want to show repeated elements in the column. So it means like groupping.
How can I group the results in controller with linq.
Sorting might also help if I can sort by first element and then 2nd etc.
Another idea also works that if I can split into 3 1D arrays? So at the end i would have array1 ={A,A,D,A}, array2={B,X,L,X}, array3= {C,Y,K,W}
Thanks.

You could do something like:
var array1 = new string[][]
{
new string[] {"A","B","C"},
new string[] {"A","X","Y"},
new string[] {"D","L","K"},
new string[] {"A","X","W"},
};
var s = array1.Select(a => string.Concat(a)).ToList();
s.Sort();
// Now you have them sorted as a list of strings, do what you want...
this will not limit you to 3 entries (didn't like the hardcoded [0],[1] etc...)

Your problem should be split into two subproblems. First, you need to sort the array1; second, you need out array1 using the fact the array1 is sorted.
You can't use grouping instead of sorting, cause a grouping is not guarantee that subarrays with the same first element will follow each other.
var array1 = new List<IList<string>>
{
new List<string> {"A", "X", "Y"},
new List<string> {"A", "X", "W"},
new List<string> {"A", "B", "C"},
new List<string> {"D", "L", "K"},
};
var array2 = from a in array1
orderby a[0], a[1], a[2]
select a;
var array3 = array2.ToList();
Now you can use array2 in Razor:
#if (array2.MoveNext())
{
#array2.Current[0], #array2.Current[1], #array2.Current[3]<br />
var lastElement = array2.Current;
while (array2.MoveNext())
{
if (array2.Current[0] != lastElement[0])
{
#array2.Current[0],
}
else if (array2.Current[1] != lastElement[0])
{
#array2.Current[1],
}
#array2.Current[2]
lastElement = array2.Current;
}
}

Related

How to check if an element inside a List of string array exists in another List of string array

I basically want to know if a string array from one list exists in another list of string array
So for example:
List 1:
{"A", "R1"}
{"A", "R2"}
List 2:
{"A", "R1"}
{"B", "R1"}
{"B", "R2"}
Then If I loop in List 1 to check whether it exists in List 2 the results will be:
true
false
I want to do it in LINQ if possilbe
You can use
Any and SequenceEqual
for this.
using System.Collections.Generic;
List<string[]> testSet = new List<string[]>
{
new string[] { "A", "R1" },
new string[] { "A", "R2" }
};
List<string[]> resultSet = new List<string[]>
{
new string[] { "A", "R1" },
new string[] { "B", "R1" },
new string[] { "B", "R2" }
};
// Checks if the value is found anywhere in the list
bool IsArrayInList(string[] value, List<string[]> list)
{
return list.Any(value.SequenceEqual);
}
foreach (var val in testSet)
{
Console.WriteLine(IsArrayInList(val,resultSet));
}
Console.ReadLine();
I would suggest a combination of .Any() and .SequenceEqual() or .All()
Example:
var list1 = new string[][]
{
new string[] { "A", "R1" },
new string[] { "A", "R2" },
};
var list2 = new string[][]
{
new string[] { "A", "R1"},
new string[] { "B", "R1"},
new string[] { "B", "R2"},
};
var itemToFind = list1.First();
// Option 1
var isInList2 = list2.Any(i => i.SequenceEqual(itemToFind));
// Option 2
var isInList2Option2 = list2.Any(item => item.All(innerItem => itemToFind.Contains(innerItem)));
As-needed, you can improve these to account for ordering, case-insensitivity, exact number of arguments, etc...
Option 1 will find any matches where the inner sequence is in the same order, same-casing as what you are looking for.
Option 2 will find any matches where the inner sequence contains all of the values of the sequence you are checking for.
Hopefully this points you in the right direction at least.

Comparing elements inside a list in c#

I want to compare elements inside a single List in C#. I need to check whether same data is there in list or not . Can anybody help me with this?
You can try this, for example:
var collection = new List<double>(new double[] { 10, 20, 11, 10, 20, 44 });
var info = collection.GroupBy(e => e).ToDictionary(e => e.Key, e => e.Count());
Here info contain a double value as a key and number of this number in collection as value.
And this construction you can use with any type of List elements.
You could use the LINQ extention methods
here is an example of LINQ comparing lists:
list<string> arr1 = new list<string>(){ "A", "b", "C," };
list<string> arr2 = new list<string>(){ "A", "b", "C," };
Compare the above arrays with the SequentialEqual() Method
bool result = arr3.SequentialEqual(arr2);
The Boolean result will contain true as the items in both lists are equal
Hope this helps
If you just want to know if there is more than one item in the list has the same value you can use this function..
public bool HasSameData<T>(List<T> myList)
{
return myList.Distinct().Count() != myList.Count();
}
note that this will work with any type.
void Main()
{
var myList = new List<int> {1,2,3,4,5,6,7,8,9};
var myList2 = new List<int> {1,1,3,4,5,6,7,8,9};
Console.WriteLine(HasSameData(myList));
Console.WriteLine(HasSameData(myList2));
var myList3 = new List<String> {"hello","world","foo","bar"};
var myList4 = new List<String> {"hello","foo","foo","bar"};
Console.WriteLine(HasSameData(myList3));
Console.WriteLine(HasSameData(myList4));
Console.ReadLine();
}
OUTPUT:
False
True
False
True

Convert jagged array of string to list of list of string in C#

I want to convert string[][] to List<List<string>>.
eg.
List<List<string>> listOfListReturned = new List<List<string>>();
string[][] twoDArrOfString = new string[2][];
I want to convert twoDArrOfString to listOfListReturned
Please suggest, how to do it?
Regards,
Vivek
Something like the following will also work:
string[][] twoDArrOfString = new string[2][];
var res = twoDArrOfString
.Where(inner => inner != null) // Cope with uninitialised inner arrays.
.Select(inner => inner.ToList()) // Project each inner array to a List<string>
.ToList(); // Materialise the IEnumerable<List<string>> to List<List<string>>
You need to handle nulls if the inner arrays have not been initialised.
If you aren't going to enumerate through all of these, you might want to drop the final ToList and simply work against the IEnumerable<List<string>> to avoid resolving all inner lists if you don't need to (taking advantage of the deferred execution of enumerables).
Any reason in particular why you are doing this?
List<List<string>> listOfListReturned = new List<List<string>>();
string[][] twoDArrOfString = new string[2][];
twoDArrOfString[0] = new[] {"a", "b"};
twoDArrOfString[1] = new[] {"c", "d"};
foreach (var s in twoDArrOfString)
{
listOfListReturned.Add(new List<string>(s));
}
Or
var result = twoDArrOfString.ToList();
var listOfList = result.Select(x => x.ToList()).ToList();
Not tested just imagine it :)
for (int i = 0; i < twoDArrOfString.Length; i++)
{
for (int j = 0; j < twoDArrOfString[i].Length; j++)
{
listOfListReturned[i].Add(twoDArrOfString[j].ToString());
}
listOfListReturned.Add(listOfListReturned[i]);
}
A more linq-ish version might be
List<List<string>> listOfListReturned = new List<List<string>>()
{
new List<string> {"A", "B"},
new List<string> {"C", "D"},
};
string[][] twoDArrOfString = new string[2][]
{
new [] {"A", "B"},
new []{"C", "D"},
};
var actual = twoDArrOfString.Select(arr => new List<string>(arr)).ToList();
for (var idx = 0; idx < listOfListReturned.Count; idx++) {
CollectionAssert.AreEqual(listOfListReturned[idx], actual[idx]);
}
EDIT: Adam's solution above allowing for empty rows is better.

Jagged arrays, populating them from a List<string>

User enters a series of values into textboxes:
Textbox 1: 10,9,8,7
Textbox 2: 1,2,3,4
Id then like to sort these two string and populate a List<string>. Once sorted (already figured out how to do that part), id like to create a jagged array of the inputs like so:
string[][] Arr = new string[2][];
Arr[0] = new string[] { "10", "9", "8", "7" };
Arr[1] = .....
but instead of manually typing in the values, id like to use the List<string> mentioned above.
Is this possible (thus far, my attempts have failed rather miserably)? If not, could someone suggest a possible alternative approach?
Thanks for your time!
EDIT: Based on the answers, I got it working. Sorry again for not making it clear what I meant by sort.
List<string> tempString = new List<string>();
tempString.Add("10,9,8,7");
tempString.Add("1,2,3");
string[][] Arr = new string[2][];
for (int x = 0; x < 2; x++)
{
string[] values = tempString[x].Split(',').ToArray();
Arr[x] = values;
}
Create lists from the strings:
List<string> list1 = new List<string>(textbox1.Text.Split(','));
List<string> list2 = new List<string>(textbox2.Text.Split(','));
Sort the lists:
list1.Sort();
list2.Sort();
Now you can easily create arrays from the lists:
string[][] Arr = new string[2][];
Arr[0] = list1.ToArray();
Arr[1] = list2.ToArray();
If you want to do it in the other order, i.e. first sort then split, it would be:
List<string> list = new List<string>();
list.Add(textbox1.Text);
list.Add(textbox2.Text);
list.Sort();
string[][] Arr = new string[2][];
Arr[0] = list[0].split(',');
Arr[1] = list[1].split(',');
Arr[0] = textBox1.Text.Split(',');
Arr[1] = textBox2.Text.Split(',');
EDIT If you need preprocessing of the lists, you can just do it like so:
var array1 = textbox1.Text.Split(',').OrderBy(x => x).ToArray();
var array2 = textbox2.Text.Split(',').OrderBy(x => x).ToArray();
// extra processing here
string[][] Arr = new string[2][];
Arr[0] = array1;
Arr[1] = array2;
string[][] Arr = new string[]{textBox1.Text, textBox2.Text} //<--or "tempString"
.Select(s => s.Split(','))
.ToArray();

how can compare items of two lists with linq?

I have two lists and one of them has 5 elements and the other one has 4 elements. They have some same elements but they have different elements too. I want to create a list with their different element. How can i do it?
Note: 5 elements list is my main list.
What about this?
var list1 = new List<int>( new []{1,2,3,4,5});
var list2 = new List<int>( new []{1,3,4});
var list3 = list1.Except( list2);
In this case, list3 will contain 2 and 5 only.
EDIT
If you want the elements from both sets that are unique, the following code should suffice:
var list1 = new List<int>( new []{1,2,3,4,5});
var list2 = new List<int>( new []{1,3,4,7});
var list3 = list1.Except(list2).Union(list2.Except(list1));
Will output 2,5 and 7.
If you're curious, the opposite of this is called Intersect
string[] collection1 = new string[] { "1", "7", "4" };
string[] collection2 = new string[] { "6", "1", "7" };
var resultSet = collection1.Intersect<string>(collection2);
foreach (string s in resultSet)
{
Console.WriteLine(s);
}

Categories

Resources