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

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.

Related

fill lists with another list with conditions [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a list:
List<string> letters = {"a", "b", "c", "d", "e", "f"};
and I have another lists that contains another strings:
List<string> myList1 = { "f3", "g4", "h5" };
List<string> myList2 = { "z5", "w7", "q9" };
List<string> myList3 = { "k5", "n7" };
I want to fill myLists with letters list with conditions:
Every list can contain 5 elements in total and don't add a letter twice for the same list.
In the example above,
myList1 = { "f3", "g4", "h5", "a", "b"};
myList2 = { "z5", "w7", "q9", "c", "d"};
myList3 = { "k5", "n7", "e", "f", "d" };
regarding to myList3, d was added randomly (don't forget that I don't want to add "e" or "f" twice).
Please note that if I had this case:
List<string> myList1 = { "f3", "g4", "h5", "t3", "u6" };
List<string> myList2 = { "z5", "w7", "q9", "k9" };
List<string> myList3 = { "k5", "n7", "d3", "n6" };
The output is:
myList1 = { "f3", "g4", "h5", "t3", "u6" };
myList2 = { "z5", "w7", "q9", "k9", "a" };
myList3 = { "k5", "n7", "d3", "n6", "b" };
If it helps, myList1 has more/equal elements than myList2 and myList3 when it's declared.
I tried to do it, but I have lots of conditions that it's unreadable.
Any help appreciated.
There is lot of ways to approach it, would have been better had you shared your approach and we could help you with it. Anyways,following is one approach you could opt.
You could write an extension method called Fill.
public static class Extension
{
public static IEnumerable<T> Circle<T>(this IEnumerable<T> list, int startIndex)
{
return list.Skip(startIndex).Concat(list.Take(startIndex));
}
public static void Fill<T>(this List<T> source, List<T> reference, int maxCount,ref int index)
{
if(source.Count() >= maxCount) return;
var difference = source.Count() - maxCount;
var newReferenceList = reference.Circle(index);
source.AddRange(newReferenceList.Where(x=>!source.Contains(x)).Take(maxCount- source.Count()));
index+=Math.Abs(difference);
if(index > maxCount) index = 0;
}
}
And then in your client,
int index = 0;
myList1.Fill(letters,5,ref index);
myList2.Fill(letters,5,ref index);
myList3.Fill(letters,5,ref index);
I think that this is what you are looking for:
public MainWindow()
{
InitializeComponent();
letters = new List<string> { "a", "b", "c", "d", "e", "f" };
myList1 = new List<string> { "f3", "g4", "h5" };
myList2 = new List<string> { "z5", "w7", "q9" };
myList3 = new List<string> { "k5", "n7" };
FillLists(letters, new List<List<string>> { myList1, myList2, myList3 });
}
private void FillLists(List<string> listToFillWith, List<List<string>> allLists)
{
char lastItemInList = listToFillWith.Last()[0]; //We get the last item inside the listToFillWith list and with the [0] we convert this string to a char
foreach (List<string> list in allLists) //We loop through each list inside allLists
{
while(list.Count != 5) //While either list 1, 2 or 3 does not have 5 items
{
if (listToFillWith.Count > 0) //Make sure our listToFillWith still has items to fill our list
{
list.Add(listToFillWith[0]); //Add the first item from listToFillWith to our list
listToFillWith.Remove(listToFillWith[0]); //Remove the first item from listToFillWith so we don't add it again
}
else //If listToFillWith is empty
{
char nextLetter;
//Here we check if the last item in the listToFillWith is a Z or z
if (lastItemInList == 'z')
{
nextLetter = 'a';
}
else if (lastItemInList == 'Z')
{
nextLetter = 'A';
}
else //If the last item in the listToFillWith is not a Z or z we get the last letter and go to the next letter in the alphabet
{
nextLetter = (char)(((int)lastItemInList) + 1);
}
list.Add(nextLetter.ToString()); //Add the next letter in the alphabet to the list
}
}
}
}

How can I use an array item with Interlocked.CompareExchange

I'm familiar with using Interlocked.CompareExchange() with plain objects. However I'd like to use it with the member of an array:
string[] myArray = new string[] { "A", "B", "C" };
string myStr = (string) Interlocked.CompareExchange(ref myArray[0], null, myArray[0]);
// myArray[0] == null
How can I accomplish this?
I am using it like this
string[] myArray = new string[] { "A", "B", "C" };
string myStr = Interlocked.CompareExchange(ref myArray[0], "F", myArray[0]);
foreach (var item in myArray)
{
Console.WriteLine(item.ToString());
}
And this is the out put
F B C
Everything is Fine.
I don't see the problem. You are setting the first string in the array to null. And that's why it's null. This is how you use it:
string[] myArray = new string[] { "A", "B", "C" };
string myStr = Interlocked.CompareExchange(ref myArray[0], "ASDF" /* VALUE */,
myArray[0]);
//myArray[0] == "ASDF" <- VALUE YOU SET

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

groupping/sorting/splitting 2D list/array

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;
}
}

C# : How to get running combination from two List<String> based on a master list

Dear all , this is something like my previous question How to get moving combination from two List<String> in C#?
I'm having a masterlist and two childlist like below
List<String> MasterList = new List<string> { "A", "B", "C", "D", "E" };
List<String> ListOne = new List<string> { "A", "B", "C" };
List<String> ListTwo = new List<String> { "B", "D" };
I just need to get the running combination from the above list for that i'm using like(previous question's answer(Thanks Danny Chen))
List<String> Result = new List<string>();
Result = ListOne.SelectMany((a, indexA) => ListTwo
.Where((b, indexB) => ListTwo
.Contains(a) ? !b.Equals(a) && indexB > indexA :
!b.Equals(a)).Select(b => string.Format("{0}-{1}", a, b))).ToList();
so the Result list will contain
"A-B"
"A-D"
"B-D"
"C-B"
"C-D"
Now my problem is the sorting issue
In the above result the fourth entry is C-B but it should be B-C. Because in the MasterList the C is after B.
How to do this in my existing linq .
Please help me to do this.
Not really clear on the exact requirement here, so does the MasterList dictate which of the two items should appear first? What about the order of the X1-X2 list? i.e. should B-C appear before B-D because C appears before D in the MasterList?
Anyway, here's something that produces the result you've asked for so far:
List<String> MasterList = new List<string> { "A", "B", "C", "D", "E" };
List<String> ListOne = new List<string> { "A", "B", "C" };
List<String> ListTwo = new List<String> { "B", "D" };
ListOne.SelectMany(i =>
ListTwo.Where(i2 => i != i2)
.Select(i2 =>
{
if (MasterList.IndexOf(i) < MasterList.IndexOf(i2))
return string.Format("{0}-{1}", i, i2);
else
return string.Format("{0}-{1}", i2, i);
}
));
outputs:
A-B
A-D
B-D
B-C
C-D

Categories

Resources