Пересечь два списка в C # - PullRequest
       2

Пересечь два списка в C #

43 голосов
/ 25 августа 2011

У меня есть два списка:

  List<int> data1 = new List<int> {1,2,3,4,5};
  List<string> data2 = new List<string>{"6","3"};

Я хочу сделать что-то вроде

var newData = data1.intersect(data2, lambda expression);

Лямбда-выражение должно возвращать true, если data1[index].ToString() == data2[index]

Ответы [ 4 ]

67 голосов
/ 25 августа 2011

Вам необходимо сначала преобразовать data1, в вашем случае, вызвав ToString() для каждого элемента.

Используйте это, если хотите вернуть строки.

List<int> data1 = new List<int> {1,2,3,4,5};
List<string> data2 = new List<string>{"6","3"};

var newData = data1.Select(i => i.ToString()).Intersect(data2);

Используйте это, если хотите вернуть целые числа.

List<int> data1 = new List<int> {1,2,3,4,5};
List<string> data2 = new List<string>{"6","3"};

var newData = data1.Intersect(data2.Select(s => int.Parse(s));

Обратите внимание, что это вызовет исключение, если не все строки являются числами. Таким образом, вы могли бы сначала сделать следующее:

int temp;
if(data2.All(s => int.TryParse(s, out temp)))
{
    // All data2 strings are int's
}
7 голосов
/ 25 августа 2011

С точки зрения производительности Если два списка содержат количество элементов, которые существенно различаются , вы можете попробовать такой подход (используя условный оператор?:):

1. Сначала вам нужно объявить конвертер:

Converter<string, int> del = delegate(string s) { return Int32.Parse(s); };

2.При использовании условного оператора:

var r = data1.Count > data2.Count ?
 data2.ConvertAll<int>(del).Intersect(data1) :
 data1.Select(v => v.ToString()).Intersect(data2).ToList<string>().ConvertAll<int>(del);

Вы преобразовываете элементы более короткого списка в соответствие с типом более длинного списка. Представьте скорость выполнения , если ваш первый набор содержит 1000 элементов, а второй - только 10 (или наоборот, как это не имеет значения); -)

Поскольку вы хотите получить результат в виде списка, в последней строке вы конвертируете результат ( только результат ) обратно в int.

3 голосов
/ 10 сентября 2018

Если у вас есть объекты, а не структуры (или строки), вам придется сначала пересечь их ключи, а затем выбрать объекты по этим ключам:

var ids = list1.Select(x => x.Id).Intersect(list2.Select(x => x.Id));
var result = list1.Where(x => ids.Contains(x.Id));
0 голосов
/ 16 ноября 2016
public static List<T> ListCompare<T>(List<T> List1 , List<T> List2 , string key )
{
    return List1.Select(t => t.GetType().GetProperty(key).GetValue(t)).Intersect(List2.Select(t => t.GetType().GetProperty(key).GetValue(t))).ToList();


}
...