Javascript JS Lodash:多维数组到对象,带有扭曲
我从多维数组开始,如下所示:Javascript JS Lodash:多维数组到对象,带有扭曲,javascript,object,multidimensional-array,underscore.js,lodash,Javascript,Object,Multidimensional Array,Underscore.js,Lodash,我从多维数组开始,如下所示: [ ['prop1', 'prop2', 'prop3', 'prop3'], ['val1', 'val2', 'val3', 'val4'] ] 我需要在这样一个对象中变换它: { prop1: 'val1', prop2: 'val2', prop3: ['val3', 'val4'] } 通常我可以使用.object(数组[0],数组[1])来解决这个问题,但是重复键prop3的存在让事情变得复杂了很多 实际\对象将设置prop
[
['prop1', 'prop2', 'prop3', 'prop3'],
['val1', 'val2', 'val3', 'val4']
]
我需要在这样一个对象中变换它:
{ prop1: 'val1',
prop2: 'val2',
prop3: ['val3', 'val4']
}
通常我可以使用
.object(数组[0],数组[1])
来解决这个问题,但是重复键prop3
的存在让事情变得复杂了很多
实际<代码>\对象将设置prop3:'val4'
,擦除val3
有人对我如何实现上述结果有想法吗
谢谢你我可能会这样做,这很容易变成下划线混音:
var arr = [
['prop1', 'prop2', 'prop3', 'prop3'],
['val1', 'val2', 'val3', 'val4']
],
keys = arr[0],
vals = arr[1],
obj = {};
keys.forEach( function( name, index )
{
if ( !Object.prototype.hasOwnProperty.call(obj, name) )
{
obj[name] = vals[index];
}
else
{
if ( obj[name] instanceof Array )
{
obj[name].push( vals[index] );
}
else
{
var val = obj[name];
obj[name] = [val, vals[index]];
}
}
} );
(变成混音)
只需压缩数组,然后使用自定义reduce就可以了。如果您的数据
arr
可以包含两个以上的集合,那么采用这种方法应该非常简单
_.mixin({
asArray: function(value) {//simple helper from https://github.com/jashkenas/underscore/pull/1467
if (value == null) return [];
if (value.length === +value.length && !_.isString(value)) return _.toArray(value);
return [value];
}
});
var arr = [
['prop1', 'prop2', 'prop3', 'prop3'],
['val1', 'val2', 'val3', 'val4']
];
/* ... */
_.chain(arr)
.zip()
.reduce(function(memo, propKey) {
if(_.has(memo, propKey[0])) { // property already in the object. Make array if necessary and insert item at end
(memo[propKey[0]] = _.asArray(memo[propKey[0]])).push(propKey[1]); //push value into object
}
else {
memo[propKey[0]] = propKey[1];
}
return memo;
}, {})
.value();
产生:{“prop1”:“val1”、“prop2”:“val2”、“prop3”:[“val3”、“val4”]}
如果不想混入,可以轻松更换
asArray
。请参阅上一版本。为了完整起见,我想提及此方法:
-或(新的)u.object()
创建由键和值数组组成的对象。提供单个二维数组,即[key1,value1],[key2,value2]]或两个数组,一个键和一个对应值
范例
不幸的是,它没有为一个键将多个值合并到一个数组中:
_.object(['key1', 'key2'], [1,2]);
// { key1: 1, key2: 2 }
_.object(['key1', 'key1'], [1,2]);
// { key1: 2 }
_.object(['key1'], [1,2]);
// { key1: 1 }
因此,这并不是您的答案的真正解决方案,但我认为注意这个函数仍然很有价值。数组中是否总是有2个项目,或者可以有更多项目?这些重复的属性名称是否总是彼此相邻?值也可以是数组吗?为了回答这两个问题:-每个键可以有1个以上的副本-不,它们不一定在数组中相邻---PS:我们不能至少在这些逗号中放换行符吗?似乎无法格式化此
!obj[name]
不足。如果obj[name]=false
或任何非真实值也typeof x=='array'
不是一个thingFWIW,那么另一个使用下划线方法的示例几乎完全以18442.733ms计时,而在我上面的回答中仅使用u.each()方法需要5.314ms。如果我把它取出来,改为使用keys.forEach(),它会将时间降低到0.118ms。重点是,如果您可以避免使用库,它会更快。:)obj[name].isArray
不是什么东西。您需要Array.isArray(obj[name])
。注意:如果您想写一行(并且必须反复使用),这些特性中的许多都需要ES5正确地检查数组并将其转换为mixin,@OlivierClément.@jacobroufa如果你想对你的实现进行基准测试并制作一个jsperf示例,请修改我的帖子以反映你建议的更改并添加一个jsperf示例比较。您好,谢谢您的回答-事实上,这似乎没有什么作用;按原样,结果是:Object{prop1,prop2,prop3,prop3:undefined,val1,val2,val3,val4:undefined}没有zip:Object{prop1:“prop2”,val1:“val2”}这也不是我想要的---我不确定为什么也需要zip,因为它似乎只是将我的数组包装成更多的数组…?哇,抱歉,我在修订之间破坏了代码;)。我使用.zip
将数组分组为[key,value]
格式的子数组,以便于处理。
_.object(['key1', 'key2'], [1,2]);
// { key1: 1, key2: 2 }
_.object(['key1', 'key1'], [1,2]);
// { key1: 2 }
_.object(['key1'], [1,2]);
// { key1: 1 }