[英]JS Lodash: Multidimensional array to object, with a twist
I start with multi-dimensional array like so: 我从多维数组开始,如下所示:
[
['prop1', 'prop2', 'prop3', 'prop3'],
['val1', 'val2', 'val3', 'val4']
]
I need to transform this in an object like this one: 我需要在像这样的对象中转换它:
{ prop1: 'val1',
prop2: 'val2',
prop3: ['val3', 'val4']
}
Normally I could use _.object(array[0], array[1])
to solve this but the presence of the duplicate key prop3
complicates things quite a bit; 通常我可以使用_.object(array[0], array[1])
来解决这个问题,但重复键prop3
的存在使得事情变得非常复杂;
Actual _.object
will set prop3: 'val4'
, erasing val3
实际_.object
将设置_.object
prop3: 'val4'
,删除val3
Anyone got an idea on how I could achieve the results presented above? 任何人都知道如何实现上述结果?
Thank you 谢谢
I'd probably do something like this, which would be easy enough to turn into an underscore mixin: 我可能会做这样的事情,这很容易变成下划线mixin:
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]];
}
}
} );
Example in a fiddle. 小提琴中的例子。 (turned into a mixin) (变成了混合)
jsPerf comparison with underscore-based code. jsPerf与基于下划线的代码比较。
Simply zipping the arrays and then using a custom reduce should do the trick. 简单地压缩数组然后使用自定义reduce应该可以解决问题。 Should be pretty simple to adapt this if your data arr
can contain more than 2 collections. 如果您的数据arr
可以包含2个以上的集合,那么调整它应该非常简单。
_.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();
Produces: {"prop1":"val1","prop2":"val2","prop3":["val3","val4"]}
产生: {"prop1":"val1","prop2":"val2","prop3":["val3","val4"]}
The asArray
can be easily replaced if you don't want to mixin. 如果你不想混合,可以很容易地替换asArray
。 See previous revision. 见前一版本。
Just for completeness I wanted to mention this method: 为了完整起见,我想提一下这个方法:
http://lodash.com/docs#zipObject - or (new) _.object() http://lodash.com/docs#zipObject - 或(新)_.object()
Creates an object composed from arrays of keys and values. 创建一个由键和值数组组成的对象。 Provide either a single two dimensional array, ie [[key1, value1], [key2, value2]] or two arrays, one of keys and one of corresponding values. 提供单个二维数组,即[[key1,value1],[key2,value2]]或两个数组,一个键和一个相应的值。
Example 例
_.zipObject(['fred', 'barney'], [30, 40]);
// → { 'fred': 30, 'barney': 40 }
Unfortunately, it doesn't combine several values into an array for one key: 不幸的是,它没有将几个值组合成一个键的数组:
_.object(['key1', 'key2'], [1,2]);
// { key1: 1, key2: 2 }
_.object(['key1', 'key1'], [1,2]);
// { key1: 2 }
_.object(['key1'], [1,2]);
// { key1: 1 }
So this is not really the solution to your answer but I think it's still valuable to take note of this function. 所以这不是你的答案的真正解决方案,但我认为注意这个功能仍然很有价值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.