Как найти кортеж с минимальным элементом в массиве кортежа - PullRequest
1 голос
/ 11 июля 2020

У меня есть этот код:

(int, int)[] tupleArray = { (3, 2), (4, 1) };

Кортеж с минимальным элементом в массиве (4, 1), но этот код

tupleArray.Min(); 

возвращает (3, 2). Я думаю, что этот метод сравнивает только Item1. Есть ли простое решение моей проблемы?

Ответы [ 4 ]

2 голосов
/ 11 июля 2020

Вы можете использовать OrderBy в сочетании с Math.Min

var min = tupleArray
    .OrderBy(t => Math.Min(t.Item1, t.Item2))
    .First()

или Aggregate, что должно быть быстрее:

Func<(int, int), int> min = t => Math.Min(t.Item1, t.Item2); // just not to repeat comparison
var min = tupleArray.Aggregate((acc, t) =>  min(t) > min(acc) ? acc: t);
1 голос
/ 11 июля 2020

Вариант Enumerable.Aggregate со встроенным кортежем ((int.MaxValue, int.MaxValue)), используемым как для сравнения, так и для хранения, аналогично тому, что опубликовал Гуру Строн. tupleArray объявлен как именованный кортеж. Я добавил в массив еще несколько значений, чтобы было понятнее, что могут возвращать эти методы.

Это вернет первый элемент в массиве с минимальным значением (4, 1).

(int i1, int i2)[] tupleArray = { (3, 2), (4, 1), (1, 4), (2, 2) };

var min = tupleArray.Aggregate((int.MaxValue, int.MaxValue), (tm, t)
    => (Math.Min(t.i1, t.i2) < Math.Min(tm.Item1, tm.Item2)) ? t : tm);

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

(int i1, int i2) min = (int.MaxValue, int.MaxValue);
min = tupleArray.Select(t => 
    { return min = (Math.Min(t.i1, t.i2) < Math.Min(min.i1, min.i2)) ? t : min; }).Last();

(здесь значение, присвоенное min, (int.MaxValue, int.MaxValue), может быть ранее сохраненное значение, объявленное как коллекция tupleArray)

1 голос
/ 11 июля 2020

Вы можете использовать это быстро:

(int, int)[] tupleArray = { (3, 2), (4, 1) };

(int, int) min = (int.MaxValue, int.MaxValue);

foreach ( var item in tupleArray )
  if ( item.Item1 < min.Item1 || item.Item2 < min.Item2
    || item.Item1 < min.Item2 || item.Item2 < min.Item1 )  // Additional tests from @itsme86 
    min = item;

Console.WriteLine(min);

Вывод

(4, 1)
0 голосов
/ 11 июля 2020

Вы можете использовать оператор MinBy из библиотеки MoreLinq .

Возвращает минимальные элементы данной последовательности на основе заданная проекция.

public static IExtremaEnumerable<TSource> MinBy<TSource, TKey>(
    this IEnumerable<TSource> source, Func<TSource, TKey> selector);

Пример использования:

var minTuple = tupleArray.MinBy(t => Math.Min(t.Item1, t.Item2)).First();

Кстати, MinBy возвращал одно значение в версиях библиотеки до 3.0 ( цитата ).

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