C #, получить индексы объектов из списка, по нескольким условиям, используя Linq - PullRequest
0 голосов
/ 28 ноября 2018

Выражения linq сложны для меня, когда мне нужно выполнить сложный поиск по списку.

Допустим, у меня есть список

public class Object {
    var length;
    var height;
    var depth;
}

Как отфильтровать идентификатор объекта по максимальной длине, еслисуществует более одного индекса, затем выполняется фильтрация по максимальной ширине, если существует более одного индекса, затем выполняется фильтрация по максимальной глубине, если более одного индекса возвращает первый.

я нашел максимальные значения:

float maxWidth = boxes.Max(x => x.width);
float maxHeight = boxes.Max(x => x.height);
float maxDepth = boxes.Max(x => x.depth);

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

private GameObject largestSurfaceBox()
{

    //find max length.width, height box
    float maxWidth = boxes.Max(x => x.GetComponent<Box>().dimensions.x);
    List<GameObject> maxWidthBoxes = new List<GameObject>();

    for (int i = 0; i < boxes.Count; i++) {
        if (System.Math.Abs(boxes[i].GetComponent<Box>().dimensions.x - maxWidth) < float.Epsilon) {
            maxWidthBoxes.Add(boxes[i]);
        }
    }

    float maxHeight = maxWidthBoxes.Max(x => x.GetComponent<Box>().dimensions.y);
    List<GameObject> maxHeightBoxes = new List<GameObject>();

    for (int i = 0; i < maxWidthBoxes.Count; i++) {
        if (System.Math.Abs(maxWidthBoxes[i].GetComponent<Box>().dimensions.y - maxHeight) < float.Epsilon) {
            maxHeightBoxes.Add(boxes[i]);
        }
    }

    List<GameObject> maxDepthBoxes = new List<GameObject>();
    float maxDepth = maxHeightBoxes.Max(x => x.GetComponent<Box>().dimensions.z);

    for (int i = 0; i < maxHeightBoxes.Count; i++) {
        if (System.Math.Abs(maxHeightBoxes[i].GetComponent<Box>().dimensions.z - maxDepth) < float.Epsilon) {
            maxDepthBoxes.Add(boxes[i]);
        }
    }

    return maxDepthBoxes[0];
}

Как сделать этот элегантный способ linq с помощью операторов if, если это возможно?

1 Ответ

0 голосов
/ 29 ноября 2018

Похоже, вы ищете "MaxBy" с несколькими условиями.Существует несколько возможных вариантов использования расширений LINQ.Самый простой и, вероятно, самый неэффективный - это заказать и получить первый или последний элемент:

GameObject result = boxes.OrderBy(x => x.width)
                          .ThenBy(x => x.height)
                          .ThenBy(x => x.depth)
                          .LastOrDefault();

Другой вариант заключается в реализации пользовательского компаратора в вашем классе, чтобы вы могли сделатьпросто boxes.Max(),
или используйте класс, который уже реализует его, такой как Tuple (приводит к исключению, если коллекция пуста):

GameObject result = boxes.Max(x => Tuple.Create(x.width, x.height, x.depth, x)).Item4;

Выше также не самый эффективный, так каксоздает Tuple для каждого элемента, но, вероятно, будет достаточно быстрым.Наиболее эффективным должен быть один цикл for, чтобы получить максимальный элемент без LINQ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...