merge two arrays of keys and values to an object u

2020-01-31 01:03发布

Given two arrays, one with keys, one with values:

keys = ['foo', 'bar', 'qux']
values = ['1', '2', '3']

How would you convert it to an object, by only using underscore.js methods?

{
   foo: '1', 
   bar: '2',
   qux: '3'
}

I'm not looking for a plain javascript answer (like this).

I'm asking this as a personal exercise. I thought underscore had a method that was doing exactly this, only to find out it doesn't, and that got me wondering if it could be done. I have an answer, but it involves quite a few operations. How would you do it?

8条回答
戒情不戒烟
2楼-- · 2020-01-31 01:17

I know you asked for Underscore.js solutions, but you don't need it for this. Here's a oneliner using ES7 object spread operator and dynamic keys.

keys.reduce((obj, k, i) => ({...obj, [k]: values[i] }), {})
查看更多
家丑人穷心不美
3楼-- · 2020-01-31 01:18

What you are looking for is the zip function.

zip function

Edit: It doesn't create an object but it does combine the array by creating a sub array

There's no function that exactly does what you want. But you can use the result of zip to create your object.

var arr = _.zip(['foo', 'bar', 'qux'], ['1', '2', '3']);
var i, len = arr.length;
var new_obj = [];

for(i=0; i<len; ++i)
   new_obj[arr[i][0]] = arr[i][1];
查看更多
Rolldiameter
4楼-- · 2020-01-31 01:24

Cleanest is

keys = ['foo', 'bar', 'qux']
values = ['1', '2', '3']

function Arr2object(keys, vals) {
  return keys.reduce(
    function(prev, val, i) {
      prev[val] = vals[i];
      return prev;
    }, {}
  );
}

console.log(Arr2object(keys, values));

Or, use _.reduce, but if you're using underscore you already have _.object.

查看更多
迷人小祖宗
5楼-- · 2020-01-31 01:31

How about:

keys = ['foo', 'bar', 'qux'];
values = ['1', '2', '3'];
some = {};
_.each(keys,function(k,i){some[k] = values[i];});

To be complete: another approach could be:

 _.zip(['foo', 'bar', 'qux'],['1', '2', '3'])
  .map(function(v){this[v[0]]=v[1];}, some = {});

For the record, without underscore you could extend Array.prototype:

Array.prototype.toObj = function(values){
   values = values || this.map(function(v){return true;}); 
   var some;
   this .map(function(v){return [v,this.shift()]},values)
        .map(function(v){this[v[0]]=v[1];},some = {});
   return some; 
};
// usage
var some = ['foo', 'bar', 'qux'].toObj(['1', '2', '3']);

See jsfiddle

查看更多
手持菜刀,她持情操
6楼-- · 2020-01-31 01:35

Given that this is 4 years old, and Lodash has more or less taken the place of Underscore, I thought I would share this solution using Lodash:

var keys = ['foo', 'bar', 'qux'];
var values = ['1', '2', '3'];
var obj = _.zipObject( keys, values );

Simple and clean.

查看更多
做自己的国王
7楼-- · 2020-01-31 01:38

What you need to use is the _.object method of underscore js. If object method is not present in your version of underscore.js then you will have to manually add this method to it.

keys = ['foo', 'bar', 'qux']
values = ['1', '2', '3']
_.object = function(list, values) {
  if (list == null) return {};
  var result = {};
  for (var i = 0, l = list.length; i < l; i++) {
    if (values) {
      result[list[i]] = values[i];
    } else {
      result[list[i][0]] = list[i][1];
    }
  }
  return result;
};

console.log(_.object(keys, values))
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

查看更多
登录 后发表回答