Home > other >  Select list elements contained in another list in linq
Select list elements contained in another list in linq

Time:05-21

I have a string with "|" seperators:

string s = "item1|item2|item3|item4";

a list of objects that each have a name and value:

//object
List<ItemObject> itemList = new List<ItemObject>();
itemList.Add(new ItemObject{Name="item0",Value=0});
itemList.Add(new ItemObject{Name="item1",Value=1});

//class
public class ItemObject(){
    public string Name {get;set;}
    public int Value {get;set;}
}

How could the following code be done in one line in linq?

var newList = new List<object>();
foreach (var item in s.Split("|"))
{
    newList.Add(itemList.FirstOrDefault(x => x.Name == item));
}

// Result: newList
// {Name="item1",Value=1}

CodePudding user response:

I would suggest to start from splitting the string in the beginning. By doing so we won't split it during each iteration:

List<ItemObject> newList = s
  .Split("|")
  .SelectMany(x => itemList.Where(i => i.Name == x))
  .ToList();

Or even better:

List<ItemObject> newList = s
  .Split("|") // we can also pass second argument: StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries
  .Distinct() // remove possible duplicates, we can also specify comparer f.e. StringComparer.CurrentCulture
  .SelectMany(x => itemList
    .Where(i => string.Equals(i.Name, x))) // it is better to use string.Equals, we can pass comparison as third argument f.e. StringComparison.CurrentCulture
  .ToList();

CodePudding user response:

Try this:

var newList = itemList.Where(item => s.Split('|').Contains(item.Name));

The proposed solution also prevents from populating newList with nulls from nonpresent items. You may also consider a more strict string equality check.

CodePudding user response:

string s = "item1|item2|item3|item4"; 

I don't see a need for splitting this string s. So you could simply do

var newList = itemList.Where(i => s.Contains(i.Name));

For different buggy input you can also do

s = "|"   s   "|";
var newList = itemList.Where(o => s.Contains("|"   o.Name   '|')).ToList();

CodePudding user response:

List<object> newList = itemList.Where(item => s.Split("|").Contains(item.Name)).ToList<object>();
  • Related