Underscore.js:使用在对象中找到的键从对象列表中创建映射
Posted
技术标签:
【中文标题】Underscore.js:使用在对象中找到的键从对象列表中创建映射【英文标题】:Underscore.js: create a map out of list of objects using a key found in the object 【发布时间】:2012-05-12 02:02:50 【问题描述】:我正在使用出色的 Underscore.js 库。我有一个特定的任务,我可以使用 javascript 或 jQuery 完成,但我想知道在 Underscore 中是否有某种可用的抽象我错过了。
基本上我有一个像这样的对象 -
var some_object_array = [id: "a", val: 55, id: "b", val: 1, id: "c", val: 45];
我想把它转换成 -
var some_map = "a": id: "a", val: 55, "b": id: "b", val: 1, "c": id: "c", val: 45;
我知道我可以使用_.groupBy(some_object_array, "id")
。但这会返回一个像这样的地图 -
var some_grouped_map = "a": [id: "a", val: 55], "b": [id: "b", val: 1], "c": [id: "c", val: 45];
请注意,这会按照宣传的方式进行。但我希望得到some_map
而无需自己迭代对象。
任何帮助表示赞赏。
【问题讨论】:
【参考方案1】:我认为没有什么比 groupBy 更能满足您的需求了。即使有,也不会比简单的更好:
var some_map = ;
_.each(some_object_array, function(val)
some_map[val.id] = val;
);
【讨论】:
好吧,这就是我最终所做的。但很好奇是否有更好的方法。 +1 因为我发现这种方法比_.object(_.map(...))
更直接
这就是_.chain(data).map((val)=>[val.id, val]).object().value()
的链接【参考方案2】:
还有这个方法
_.reduce(data, function (o, item) o[item.key] = item.value; return o , )
这是一个语句,内部函数中有两个语句。
【讨论】:
你不应该使用 reduce,因为它用于不同的目的(reduce 将值列表归结为单个值),基本上这是一个 hack,这会给其他开发人员带来很多困惑阅读您的代码... @user2846569 它将列表归结为单个对象。完美应用reduce
。
@OttoAllmendinger 但是,指定的归约操作使用异类参数,这是非常规的。在传统的归约函数中,您希望 a
和 b
(此处为 o
和 item
)属于同一类型。事实上,强类型语言不允许如此处所示的归约函数。【参考方案3】:
不管怎样,因为 underscore.js 你现在可以使用_.object()
var some_map = _.object(_.map(some_object_array, function(item)
return [item.id, item]
));
【讨论】:
对象上的映射如此很有用,我总是定义mapo = _.compose(_.object, _.map);
_.object()
似乎已被删除。下划线是否仍然可用?
如果我错了,请纠正我,但我认为使用 lodash 你也可以使用单个 _.transform
函数。
要扩展 @DustinGetz 的评论...也可以使用下划线混合而不是将 mapo
分配给全局范围:_.mixin(mapo: _.compose( _.object, _.map ));
_.object()
在最新版本的下划线中没有被删除【参考方案4】:
对于您的情况,您应该使用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');
【讨论】:
本案最合适的答案 这就是答案。some_grouped_map
的名称令人困惑。 indexBy
用于密钥唯一的情况。 indexOf
生成非唯一键组。
从 lodash 4 source 开始是 _.keyBy
【参考方案5】:
在这种情况下,您不需要迭代数组。不是map
,不是reduce
,不是transform
。你只需要旧的pluck
_.object(_.pluck(some_object_array, 'id'), some_object_array);
【讨论】:
【参考方案6】:对于 ES6,它是
var some_map = _.chain(some_object_array)
.map(item => [item.id, item])
.object()
.value()
【讨论】:
以上是关于Underscore.js:使用在对象中找到的键从对象列表中创建映射的主要内容,如果未能解决你的问题,请参考以下文章
如何根据 apache hive 中的键从 json 列表中提取 json 对象