Я предполагаю, что цель состоит в том, чтобы на самом деле создать изоморфизм, с помощью которого можно рассматривать такой массив как объект массивов, а также выполнять обновления.Как и в случае двунаправленной версии, например, функции R.groupBy
Рамды.
Действительно, одним из подходов было бы просто использовать R.groupBy
Рамды для реализации нового примитивного изоморфизма с использованиемL.iso
.Примерно так:
const objectBy = keyL => L.iso(
R.cond([[R.is(Array), R.groupBy(L.get(keyL))]]),
R.cond([[R.is(Object), L.collect([L.values, L.elems])]])
)
Условные обозначения необходимы, чтобы учесть вероятность того, что данные не относятся к ожидаемому типу, и отобразить результат в undefined
, если это не так.
Вот игровая площадка с вышеуказанной реализацией objectBy
, основанной на Рамде.
Используя только текущую версию частичных линз, одним из способов создания аналогичного комбинатора objectBy
будетследующим образом:
const objectBy = keyL => [
L.groupBy(keyL),
L.array(L.unzipWith1(L.iso(x => [L.get(keyL, x), x], L.get(1)))),
L.inverse(L.keyed)
]
Возможно, интересной частью выше является средняя часть, которая преобразует массив массивов в массив пар ключ-массив (или наоборот).L.unzipWith1
проверяет, что все ключи в группе совпадают, и если они этого не делают, эта группа будет сопоставлена с undefined
и отфильтрована по L.array
.При желании можно добиться более строгого поведения, используя L.arrays
.
Вот игровая площадка с вышеописанной objectBy
реализацией.