#c# #list #performance #linq
#c# #Список #Производительность #linq
Вопрос:
Учитывая список векторов, как я могу эффективно выбрать все наибольшие значения свойства среди всех членов, которые разделяют другие значения среди разных свойств.
Например, со стандартным Vector3, как бы я выбрал Vector3s, которые имеют наибольшее значение Y относительно всех других членов с одинаковыми значениями X и Z.
Мой текущий рабочий метод заключается в переборе списка следующим образом:
Vector3 current = Vector3.Zero;
List<Vector3> out = new List<Vector3>();
foreach(var member in MyList)
{
current= member;
foreach(var compare in MyList)
{
if(!predicate(current,compare))
current = compare;
}
out.Add(largest);
}
Но это не кажется особенно эффективным, поскольку выполняет n квадратов сравнений, где n — длина списка.
Любые предложения по сокращению этого до более приемлемого числа, поскольку я намерен использовать это в критически важном для производительности разделе моего кода.
Для предиката с равными значениями X и Z наибольшее значение Y
Пример ввода:
(1,1,1)
(1,2,1)
(1,4,1)
(2,3,2)
(2,5,2)
(1,4,2)
(1,2,2)
(1,1,2)
(2,5,1)
(2,4,1)
(2,9,1)
Ожидаемый результат:
(1,4,1)
(2,5,2)
(1,4,2)
(2,9,1)
Комментарии:
1. почему вы не используете linq?
2. И, пожалуйста, можете ли вы добавить пример в качестве входных данных и что вы делаете, кроме как в качестве выходных данных
3. Я записал это без LINQ долгий путь. Я не знаю способа объединить это с LINQ, отсюда и вопрос
4. В вашем примере, что
predicate
?5. @MohamadMousheimish добавлен пример ввода и вывода
Ответ №1:
Для этого вы можете использовать LINQ:
var result = vectors
.GroupBy(v => Tuple.Create(v.X, v.Z))
.Select(vg => vg.OrderByDescending(v => v.Y).First())
.ToList();
- В
GroupBy
качестве ключа будет использоваться кортежX
иZ
. - Из каждой группы мы
Select
выбираем значение с наибольшимY
значением.
Комментарии:
1. Очень приятно! Мне понравилась идея.
2. Только один вопрос по этому поводу: является ли GroupBy более эффективным за кулисами, чем то, что я настроил, выполняя сравнения n ^ 2?
3. @Azeranth пример, который вы привели в вопросе, на самом деле не возвращает тот же список, который вы «ожидаете», поэтому я не могу точно сравнить по времени.