Reputation: 25
I have a List<List<string>> Full
, build up by
for(...){
Full.Add(new List<string>());
Full[ListIndex].Add(string1);
Full[ListIndex].Add(string2);
Full[ListIndex].Add(string3);
...
}
can be read by
string2 = Full[sublistX][element1];
A List<string> Strings
contain some of the instance for string2
I want to create a new List<List<string> NewList
only contain sublist from Full[sublistX][element1]
which equals to any element in List<string>Strings
For example,
List<List<string>> Full = new List<List<string>>()
{
new List<string>() { "11", "AA", "!!", },
new List<string>() { "22", "BB", "@@", },
new List<string>() { "33", "CC", "##", },
new List<string>() { "44", "DD", "$$", },
};
List<string> Strings = new List<string>()
{
"AA", "DD",
};
I want the List<List<string> NewList
contain:
sublist0: "11", "AA", "!!"; //match "AA"
sublist1: "44", "DD", "$$"; //match "DD"
For now, I'm probably doing this in a stupid way (hardcoded)
List<List<string>> Full;
List<string> Strings;
List<List<string>> NewList;
for (int i = 0; i < Full.Count; i++)
{
if (Strings.Contains(Full[i][4]))
{
NewList.Add(new List<string>());
NewList[ListIndex].Add(Full[i][0]);
NewList[ListIndex].Add(Full[i][1]);
NewList[ListIndex].Add(Full[i][2]);
NewList[ListIndex].Add(Full[i][3]);
NewList[ListIndex].Add(Full[i][4]);
NewList[ListIndex].Add(Full[i][5]);
NewList[ListIndex].Add(Full[i][6]);
NewList[ListIndex].Add(Full[i][7]);
NewList[ListIndex].Add(Full[i][8]);
NewList[ListIndex].Add(Full[i][9]);
ListIndex++;
}
}
My question is: is there a better way to do it?
I think there could be two points that need optimizing:
for()
to traverse the whole list "Full," especially when "Full" contains a lot of sublists and "Strings" only have little elements.NewList[ListIndex].Add
from index 0 to 9. Is there a way to get the counts of sublist elements? So that I can use for(sublist elements count)
to add the NewList.Upvotes: 1
Views: 93
Reputation: 30813
List<List<string>> full = ...;
List<string> searchItems = ...;
// only filtering
var result = full.Where(l => searchItems.Any(l.Contains)).ToList();
// also copying
var result = full.Where(l => searchItems.Any(l.Contains)).Select(l => l.ToList()).ToList();
// or faster for big lists
var searchItemsSet = new HashSet<string>(searchItems);
var result = full.Where(list => list.Any(searchItemsSet .Contains)).ToList();
Upvotes: 2
Reputation: 10790
Well, you can utilize Linq as follows :
var filteredList = Full.Where(strs => strs.Any(s=> Strings.Contains(s))).ToList();
This will give you a list that includes any list that Full
at least has one element contained by Strings
list.
Upvotes: 2
Reputation: 117084
I feel that this reads a little nicer:
List<List<string>> NewList =
(
from xs in Full
where xs.Any(x => Strings.Any(s => x.Contains(s)))
select xs
).ToList();
Upvotes: 1
Reputation: 460158
You can use Intersect
...Any
:
List<List<string>> resultList = FullLIst
.Where(list => strings.Intersect(list).Any())
.ToList();
This performs better than Contains
if the lists are big.
Upvotes: 2