Общий список C # - FindAll для дочерних массивов - PullRequest
1 голос
/ 21 января 2010

Я пытаюсь найти лучший подход к фильтрации списка с помощью C # (3.5), но я не могу найти какие-либо примеры, похожие на мою ситуацию.Я открыт для использования лямбды или linq.

Уникальность по сравнению с большинством примеров, которые я обнаружил, заключается в том, что каждый элемент моего списка имеет дочерние массивы, например ...

var employees= new List<Employee>
{
    new Employee{Name = "John",Nicknames="'J','Big J','Big John'"},
    new Employee{Name = "Joshua",Nicknames="'J','Josh','Joshman'"},
}

Я бы тогдахотел бы отфильтровать этот список примерно так ...

//using linq
var matchesByNickname =
from worker in employees
where worker.Nicknames.Equals("J")
select worker;

//or lambda
var employees2 = employees
    .Where(e => Nicknames.Exists(n => n.Nickname == "J"))

Но, разумеется, поскольку псевдонимы сами по себе являются массивом, я не могу использовать .Equals или .Contains и т. д. Что было бы наилучшим подходом для фильтрации спискаэтот тип?

ОБНОВЛЕНИЕ: пытаясь сделать мой пример простым, я немного ввел вас в заблуждение.Элементы списка имеют настоящие объектные массивы, а не строки.Мой пример из реального мира - это список пользовательских объектов продукта.Объект продукта имеет свойство Regions, представляющее собой список объектов Region.Продукт может иметь ни одного, 1 или более 1 региона.Объект региона имеет имя и идентификатор.Поэтому я действительно хочу отфильтровать список продуктов для любого продукта, назначенного определенному региону.

Ответы [ 2 ]

3 голосов
/ 21 января 2010

В вашем примере Nickname - это не массив, как я его вижу. Это строка Предполагая, что это массив строк, вы можете:

var employees2 = employees.Where(e => e.Nicknames.Contains(name));

Если вы хотите оставить все как есть (строка), вы можете попробовать что-то вроде:

var employees2 = employees.Where(e => e.Nicknames.Split(',')
                                                 .Contains("'" + name + "'"));

В обоих вышеупомянутых случаях вы можете заменить Where на FindAll и получить результаты обратно в List<T> вместо IEnumerable<T> (List<T>.FindAll существует с 2.0, но Enumerable.Where является новым в 3.5).

Конечно, в идеале вы должны сделать его массивом или списком, подобным следующему, и использовать первый метод:

var employees = new List<Employee>
{
    new Employee{Name = "John",Nicknames= new [] {"J", "Big J", "Big John"}},
    new Employee{Name = "Joshua",Nicknames = new [] {"J", "Josh", "Joshman"}},
};

ОБНОВЛЕНИЕ : Ваш пример из реального мира не так сильно отличается от этого примера. Я думаю вы ищете Any вместо Contains, так как вы проверяете свойство, а не весь объект на равенство:

var filteredProducts = products
        .Where(p => p.Regions.Any(r => r.Name == "regionToSearchFor"));
0 голосов
/ 21 января 2010

Если у вас есть одинарные кавычки вокруг псевдонимов, вы можете просто заглянуть в строку для имени в одинарных кавычках.

employees.Where(x=>x.Nicknames.IndexOf("'J'") >= 0)

Редактировать: Забыл одинарные кавычки ... и> =

...