Xtend Movies пример лучший ответ

Я следовал руководству Xtend и примеру фильмов. В конце этого урока вы можете найти этот вопрос:

    @Test def void sumOfVotesOfTop2() {
      val long sum = movies.sortBy[ -rating ].take(2).map[ numberOfVotes ].reduce[ a, b | a + b ]
      assertEquals(47_229L, sum)
    }

Сначала фильмы сортируются по рейтингу, затем мы выбираем два лучших. Затем список фильмов превращается в список их numberOfVotes с помощью функции карты. Теперь у нас есть список, который можно сократить до одного Long, добавив значения.

Вы также можете использовать сокращение вместо сопоставления и уменьшения. Ты знаешь как?

Мой вопрос: какой лучший ответ на последний вопрос?

Я нашел способ вычислить одно и то же значение «суммы» без использования метода расширения map(), но мне это кажется ужасным. Вот мое решение:

assertEquals(47229, this.movies.sortBy[ -rating ].take(2).reduce[m1, m2 | new Movie('', 0, 0.0, m1.numberOfVotes + m2.numberOfVotes,null)].numberOfVotes)

Есть ли лучший (и более чистый) способ сделать это?


person Antwane    schedule 21.03.2013    source источник


Ответы (1)


Вы можете использовать fold(R seed, (R,T)=>R function) вместо reduce((T,T)=>T):

assertEquals(47229, 
  movies
    .sortBy[rating]
    .reverseView
    .take(2)
    .fold(0L) [ result, movie | result + movie.numberOfVotes ])

Обратите внимание, что map((T)=>R) не выполняет никаких немедленных вычислений, а оценивается по запросу, поэтому производительность не должна иметь значения для решения, использующего функцию карты. Тем не менее, fold весьма удобен, если вам нужно накопить результат для набора значений, где тип результата отличается от типа элемента.

person Sebastian Zarnekow    schedule 21.03.2013
comment
Я согласен, но Xtend в учебнике, вопрос 3 сказал, что можно заменить map[ numberOfVotes ].reduce[ a, b | a + b ] простым вызовом reduce, это то, чего я не понимаю. Действительно ли возможно иметь хороший способ сделать это? - person Antwane; 21.03.2013