Linq на строковом массиве
string[] listOne = new string[] { "dog", "cat", "car", "apple"};
string[] listTwo = new string[] { "car", "apple"};
Что мне нужно, это заказать listOne
по порядку предметов в listTwo
(если представить). Таким образом, новый список будет в следующем порядке:
"машина", "яблоко", "собака", "кошка"
6 ответов
var result = listTwo.Union(listOne);
ИЛИ ЖЕ
var result =listTwo.Intersect(listOne).Concat(listOne.Except(listTwo));
var result = listTwo.Where(listOne.Contains).Concat(listOne.Except(listTwo));
Первый опубликованный ответ содержит ошибку listTwo
заказ товара, пожалуйста, пренебречь ниже ответ
var result = listOne.OrderBy(i => !listTwo.Contains(i)).ToList();
результат
"car", "apple", "dog", "cat"
Вы можете использовать метод расширения Union()
var result = listTwo.Union<string>(listOne);
Так как вы используете массивы, большая часть использования linq создаст новый экземпляр некоторого вида IEnumerable
, например, ToList
или же ToArray
,
Таким образом, я предлагаю использовать Array.Sort
Сравнение:
string[] listOne=new string[] { "dog", "cat", "car", "apple" };
string[] listTwo=new string[] { "car", "apple" };
Comparison<String> comparison=
(x, y) => {
if(!listTwo.Contains(x)||!listTwo.Contains(y))
return 0;
else {
var indexOfX=Array.IndexOf(listTwo, x);
var indexOfY=Array.IndexOf(listTwo, y);
return indexOfX.CompareTo(indexOfY);
}
};
Array.Sort(listOne, comparison);
Это будет отсортировано с помощью алгоритма быстрой сортировки внутри, это алгоритм на месте.
var sub1 = listOne.Intersect(listTwo).ToList();
var sub2 = listOne.Except(listTwo);
sub1.AddRange(sub2);
Это работает, но я чувствую, что это можно сделать лучше:
var result=
from item in listOne
let existsInListTwo=listTwo.Contains(item)
let positionInListTwo=Array.IndexOf(listTwo, item)
orderby !existsInListTwo, positionInListTwo
select new {
Item=item,
position=positionInListTwo,
exists=existsInListTwo
};
Редактировать: Используя комбинацию этого и подхода Дамита, это немного более читабельно:
var result=
listOne.OrderBy(i => !listTwo.Contains(i))
.ThenBy(i => Array.IndexOf(listTwo, i))
.ToList();
var result = listOne.Union(listTwo)
.Distinct()
.OrderBy(i => !listTwo.Contains(i));