Найти минимальный элемент во вложенном списке <Список> в groovy с помощью collect?

#groovy

#groovy

Вопрос:

Я написал приведенный ниже пример поиска min элемента во вложенном List<List<String>> , который отлично работает:

 List<String> el0 = ["112", "2"]
List<String> el1 = ["11", "222", "45", "1"]
List<String> el2 = ["21", "112", "23"]

List<List<String>> container = new ArrayList<>()

container << el0
container << el1
container << el2

List<String> candidates = container.collect { it.min(new Comparator<String>() {
  @Override
  int compare(String o1, String o2) {
    return Integer.valueOf(o1) <=> Integer.valueOf(o2)

  }
}) }

String min = candidates.min()
println (min)
  

Но есть ли оптимизация / упрощение, которые можно выполнить для приведенного выше довольно подробного примера — предполагая, что элементы должны быть строками (и в будущем более сложными объектами)?

Ответ №1:

Упрощенный способ позволяет найти минимальный элемент за одну операцию после выравнивания container (минимальное уменьшение выполняется только один раз). Это может выглядеть так:

 String min = container.flatten().min{Integer.valueOf(it)}
  

Как видно, я также использовал {Integer.valueOf(it)} в качестве замыкания для реализации Comparator<String> , что вы сделали, используя анонимный класс.

Комментарии:

1. Другой вариант List<String> candidates = container*.min {Integer.valueOf(it) }

2. @tim_yates Я бы ожидал, что это приведет к созданию списка с минимальным значением в каждом подсписке… Если min() в результате не вызывается другой: container*.min{Integer.valueOf(it)}.min{Integer.valueOf(it) }

3. Да, я имел в виду с оригиналом String min = candidates.min() , как в вопросе 😉

4. Что делает контейнер *? И как называется этот «оператор»? Я пытался найти его в Google, но не нашел никаких совпадений

5. @u123 Это оператор распространения (или оператор с расширенной точкой) *. . Документация здесь . Он вызывает метод после точки на каждом элементе коллекции, к которой он применяется, создавая новую коллекцию с результатом каждого вызова; как в [1,2,3,4]*.plus(2) == [3, 4, 5, 6]