Идиома верхней треугольной петли для списков Scala
Из моего опыта в императивном программировании яя привык делать
for (i = 0; i < 1000000; i++) {
for (j = i + 1; j < 1000000; j++) {
doSomething(array[i], array[j])
}
}
изучить все уникальные пары в массиве из миллиона элементов.doSomething
это некоторая операция, которая дает тривиальные результаты по диагонали и симметричные или антисимметричные результаты вне диагонали --- это 'Поэтому я хочу работать только над верхним треугольником. (Там'второстепенный вариант этого, гдеi == j
случай интересный; тот'легко исправить.)
Я странно застреваю, пытаясь сделать это в Scala. У меня большойList
и хочу сделать что-то для всех парных комбинаций, но
list.flatMap(x => list.map(y => doSomething(x, y))
включает в себя все лишние или тривиальные случаи (в два раза больше работы) и
(0 until 1000000).flatMap({i =>
(0 until 1000000).map({j =>
doSomething(list(i), list(j))
})
})
было бы очень неправильно, потому что списки не произвольного доступа (фактор N ^ 2 слишком много работы). Я мог бы преобразовать мойLists
вArrays
, но такое чувство, что это не соответствует действительности.Lists
связаны списки, поэтомуj + 1
Элемент из моего императивного примера лишь в шаге от I 'i
м в данный момент осматриваю. Я'я уверен, что мог бы написать эффективный верхнетреугольный цикл над связанными списками в C / Python / что угодно.
Я полагаю, что пока могу просто принять коэффициент два, но это настолько распространенная ситуация, что возникает ощущение, что должно быть хорошее решение.
Кроме того, делает это "верхнетреугольная петля " есть общее имя? Я не могНе могу найти хорошую строку для поиска.
Редактировать: Вот'Вот пример плохого решения:
list.zipWithIndex.flatMap({case (x, i) =>
list.zipWithIndex.map({case (y, j) =>
if (j > i)
doSomething(x, y)
else
Nil
})
})
потому что он все еще посещает нежелательные узлы.