LINQ вопрос ... нужно получить элемент с минимальным значением

Я новичок в linq, поэтому я все еще борюсь ....

У меня есть коллекция элементов управления (каждый имеет местоположение типа Point). Мне нужно удалить элемент управления с самым низким значением Y (верхний элемент управления) из коллекции.

пример был бы наиболее признателен !

6 ответов


что-то вроде этого:

collection.Remove(collection.OrderBy(c => c.Location.Y).First());

заказ довольно дорогой, поэтому в зависимости от вашего варианта использования вы также можете найти элемент с самым низким значением, а затем удалить его:

collection.Remove(collection.First(c => c.Y == collection.Min(c2 => c2.Y)));

это перечисляет список до трех раз, как правило, это все равно должно быть быстрее, чем OrderBy, но если производительность важна для вас, то сначала измерьте.


вам просто нужно найти элемент и удалить его, это точно. Удалить очень ясно, но при поиске вы можете использовать метод Aggregate следующим образом:

collection
   .Remove(collection
       .Aggregate((c1, c2) => c1.Point.Y < c2.Point.Y ? c1 : c2)
   )
);

заказ дороже. Просто получите минимальное значение.

var lowest = (from c in collection
              where c.X == collection.Min(i => i.X)
              select c).FirstOrDefault();
collection.Remove(c);

помните, что LINQ означает Язык INtegreated запрос. То есть он предназначен для использования в качестве инструмента для запросов, а не для модификации коллекций.

тем не менее, вы можете найти элемент управления, который вам нужно удалить с помощью LINQ. Затем просто удалите его обычным способом.

// Let's say controls is a ControlCollection
var enumerable = controls.Cast<Control>();
int minimumY = enumerable.Min(c => c.Location.Y);
Control topControl = enumerable.Where(c => c.Location.Y == minimumY);

controls.Remove(topControl);

Ниже приведен метод расширения, который позволяет выбрать элемент min в отличие от значения min. Вы можете использовать так:

var lowest = collection.MinElement(x => x.Y);

затем вы можете просто удалить элемент collection.Remove(lowest).

public static T MinElement<T>(this IEnumerable<T> source, Func<T, int> selector) {
    if (source == null) {
        throw new ArgumentNullException(nameof(source));
    }

    int minValue = 0;
    T minElement = default(T);
    bool hasValue = false;

    foreach (T s in source) {
        int x = selector(s);
        if (hasValue) {
            if (x < minValue) {
                minValue = x;
                minElement = s;
            }
        } else {
            minValue = x;
            minElement = s;
            hasValue = true;
        }
    }

    if (hasValue) {
        return minElement;
    }

    throw new InvalidOperationException("MinElement: No elements in sequence.");
}

collection.Remove( collection.Min( c => c.Y ));