Подтвердить что ты не робот

Как преобразовать список карт в карту карт в immutable.js?

Предположим, что у меня есть immutable.js List следующим образом:

var xs = Immutable.fromJS([{key: "k", text: "foo"}])

Я хочу преобразовать это в карту, которая выглядит так:

var ys = Immutable.fromJS({k: {key: "k", text: "foo"}})

Как превратить xs в ys идиоматически в immutable.js?

Идиоматически я подразумеваю, что любые промежуточные структуры должны быть неизменяемыми. js структурами, и я думаю, что любые промежуточные шаги будут использовать итеративную композицию вместо создания полноразмерного промежуточного представления.

Изменить: я создал тест jsperf, сравнивая предоставленные ответы. Оба не мутирующих решения чувствуют себя довольно идиоматично для меня; Я могу продержаться и позволить голосам решить выбранный ответ или продержаться, пока мы не сможем собрать сборник примерно одинаково идиоматических методов.

4b9b3361

Ответ 1

Вы можете уменьшить список входных данных в новый файл Immutable.Map:

var ys = xs.reduce(
      function(result, item) { return result.set(item.get('key'), item); }, 
      Immutable.Map());

В этом случае промежуточное представление отсутствует, но неизменяемая карта должна быть обновлена ​​(фактически, новый экземпляр должен быть создан) на каждой итерации и что это может быть субоптимальным (в зависимости от фактической реализации Immutable.Map).

Вы можете оптимизировать его, сводя к регулярному объекту javascript и преобразовать его в неизменяемую карту в конце:

var ys = Immutable.Map(xs.reduce(
      function(result, item) { result[item.get('key')] = item; return result; }, 
      {}));

Но это, безусловно, менее идиоматично.

Ответ 2

Одним из решений может быть использование конструктора Map из списка:

const ys = Immutable.Map(xs.map(v => [v.get('key'), v]));

Ответ 3

Похоже на это, но я не уверен в промежуточных представлениях

ys = Immutable
    .fromJS([{key:'k', value:'xxx'}])
    .toKeyedSeq()
    .mapEntries(function (kv) { return [kv[1].get('key'), kv[1]]; })

PS Это странно, но я могу использовать только .toKeyedSeq, а не .toKeyedIterable, что более уместно.

Ответ 4

Вы можете поменять список карт на карту списков с помощью reduce в сочетании с mergeWith.

Уменьшить объем сбора и объединить каждый новый элемент, объединив его значения.

collection.reduce((rr, ii) => rr.mergeWith((aa, bb) => List().concat(aa, bb), ii))