Вопрос по javascript – Underscore.js: создать карту из списка объектов, используя ключ, найденный в объекте

58

Я пользуюсь отличноUnderscore.js библиотека. У меня есть конкретная задача, которую я могу хорошо выполнить с помощью JavaScript или jQuery, но мне было интересно, есть ли какая-то абстракция, доступная в Underscore, по которой я упускаю.

По сути, у меня есть такой объект -

<code>var some_object_array = [{id: "a", val: 55}, {id: "b", val: 1}, {id: "c", val: 45}];
</code>

Я хочу преобразовать это в -

<code>var some_map = {"a": {id: "a", val: 55}, "b": {id: "b", val: 1}, "c": {id: "c", val: 45}};
</code>

Я знаю, что я могу использовать_.groupBy(some_object_array, "id"), Но это возвращает карту примерно так -

<code>var some_grouped_map = {"a": [{id: "a", val: 55}], "b": [{id: "b", val: 1}], "c": [{id: "c", val: 45}]};
</code>

Обратите внимание, что это делает то, что рекламируется. Но я надеялся получитьsome_map без перебора объектов сам.

Любая помощь приветствуется.

Ваш Ответ

7   ответов
43

indexBy функция:

var some_object_array = [{id: "a", val: 55}, {id: "b", val: 1}, {id: "c", val: 45}];

var some_grouped_map = _.indexBy(some_object_array, 'id');
это & APOS; s_.keyBy в с лодаш 4source
Согласитесь, это должен быть принятый ответ.
Имяsome_grouped_map сбивает с толку.indexBy это когда ключи уникальны.indexOf создает группы неуникальных ключей.
наиболее подходящий ответ для дела
Это ответ.
88

_.object()

var some_map = _.object(_.map(some_object_array, function(item) {
   return [item.id, item]
}));
Расширить @ DustinGetz & apos; комментарий ... вместо назначения можно также использовать миксины с подчеркиваниемmapo в глобальном масштабе:_.mixin({mapo: _.compose( _.object, _.map )});
_.object() не удаляется в последней версии подчеркивания
Поправьте меня, если я ошибаюсь, но я думаю, что с lodash вы также можете использовать сингл_.transform функция.
отображение объектовso полезно, что я всегда определяюmapo = _.compose(_.object, _.map);
Это похоже на_.object() был удален. Альтернатива этому все еще доступна в подчеркивании?
2

var some_map = _.chain(some_object_array)
                .map(item => [item.id, item])
                .object()
                .value()
-1

const ar = [
    { key: '1', val: 'a' },
    { key: '2', val: 'b' },
    { key: '3', val: 'c' }
]

const obj = _.keyBy({ ...ar }, 'key')

console.log(obj)
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

30

_.reduce(data, function (o, item) { o[item.key] = item.value; return o }, {})

Который является одним утверждением с двумя утверждениями во внутренней функции.

Вы не должны использовать Редакция, так как она используется для разных целей (редукция сводит список значений в одно значение), в основном это хак, который приводит к путанице для других разработчиков, читающих ваш код ...
@ user2846569 это сводит список в один объект. Прекрасно применениеreduce.
@OttoAllmendinger Однако, указанная операция сокращения использует гетерогенные аргументы, что является нетрадиционным. В обычной функции сокращения вы хотите, чтобы вашa а такжеb (Вотo а такжеitem) быть того же типа. На самом деле, строго типизированные языки не допускают такой функции сокращения, как показано здесь.
12

что есть что-то более близкое, чем groupBy, для ваших нужд. Даже если бы это было так, это было бы не лучше, чем просто:

var some_map = {};
_.each(some_object_array, function(val) {
  some_map[val.id] = val;
});
+1, потому что я считаю этот подход более простым, чем_.object(_.map(...))
Хорошо, вот что я сделал в конце концов. Но было любопытно, есть ли лучший способ сделать это. Chantz
это то, что цепочка для_.chain(data).map((val)=>[val.id, val]).object().value()
3

mapнеreduceнеtransform, Все, что вам нужно, это старыйpluck

_.object(_.pluck(some_object_array, 'id'), some_object_array);

Похожие вопросы