#c# #linq
#c# #linq
Вопрос:
Я бы предположил, что для этого есть простой запрос LINQ, я просто не совсем уверен, как это сделать. Пожалуйста, смотрите фрагмент кода ниже, комментарий объясняет, что я хотел бы сделать:
class Program
{
static void Main(string[] args)
{
List<Person> peopleList1 = new List<Person>();
peopleList1.Add(new Person() { ID = 1 });
peopleList1.Add(new Person() { ID = 2 });
peopleList1.Add(new Person() { ID = 3 });
List<Person> peopleList2 = new List<Person>();
peopleList2.Add(new Person() { ID = 2 });
peopleList2.Add(new Person() { ID = 1 });
peopleList2.Add(new Person() { ID = 4 });
peopleList2.Add(new Person() { ID = 3 });
peopleList2.Add(new Person() { ID = 5 });
}
}
Я хотел бы выполнить запрос LINQ, чтобы предоставить мне всех людей, peopleList1
которых нет peopleList2
в том же порядке
, в котором этот пример должен дать мне трех человек:
(ID = 1, 2 и 3)
Я попытался использовать
peopleList1.Except(peopleList2)
Но это не работает в моем сценарии, потому что я также должен проверять порядок. Список 1 должен содержать элемент в той же позиции, что и список 2
Комментарии:
1. Вы пробовали что-нибудь?
2. Я пробовал Except, но он не проверяет порядок.
3. Что вы подразумеваете под «точным положением»??
4. кстати, подумайте об использовании чего-то вроде Hashset, у него есть метод поиска элементов в зависимости от элементов во втором наборе
5. Пока я понимаю… есть два списка, которые содержат объекты одного и того же типа, идентификатор является ключевым между обоими. Вы хотите проверить все записи в одном списке на соответствие всем записям в другом или под «точной позицией» вы имеете в виду, что вы хотите проверить, что элемент проверки в позиции 1 в списке 1 должен быть снова проверен «только» элемент в позиции 1 в списке 2???
Ответ №1:
В .NET List<T>
тип поддерживается массивом, поэтому наиболее эффективным способом сделать это с помощью LINQ было бы использовать перегрузку Select
, которая также обращается к индексу:
peopleList1.Where((person, index) => peopleList2[index].Id != person.Id);
Комментарии:
1. Да, в исходном примере нет элементов, которые отображаются с одинаковым индексом в обоих списках!
2. Вы проверяли это с данными OP? Потому что, когда я тестировал это, это не дает мне трех человек (ID = 1, 2 и 3), как упоминал OP!
3. Ах, я пропустил «не» часть его сообщения! Все, что нужно сделать, это изменить значение
==
to!=
в лямбда4. Также вам нужно изменить
peopleList2[index]
peopleList2[index].Id
, чтобы этот код работал.5. Готово! Я только что использовал
int
список при тестировании и забыл добавить его обратно
Ответ №2:
Я думаю, это должно быть то, что вы хотите:
var result = peopleList1.Zip(peopleList2, (f, s) => f.ID != s.ID ? f.ID : 0)
.Where(c => c > 0).ToList();
Zip
Проверяет соответствующие элементы peopleList1
и peopleList2
, и выдает последовательность результатов, которая представляет собой элементы, которые существуют, peopleList1
но не peopleList2
в том же порядке.
Ответ №3:
Это должно сделать
peopleList1.Where(x=>peopleList2.Count<peopleList1.IndexOf(x) 1||peopleList2[peopleList1.IndexOf(x)].ID!=x.ID).ToList()
Комментарии:
1. Я отредактировал ответ, чтобы учесть разъяснения в вопросе, т.е. в том же порядке
2. Но это не дает результата для примера OP.
3. Если бы были какие-либо совпадения, он вернул бы список элементов, которые совпали, в противном случае список был бы пустым. попробуйте изменить образец данных, чтобы получить совпадение, а затем проверить результат.
4. например, сделайте идентификаторы первых элементов 1 и 2 соответственно в обоих списках и test.
5. Вы проверяли это с данными OP? Потому что, когда я тестировал это, это не дает мне трех человек (ID = 1, 2 и 3), как упоминал OP!