Подтвердить что ты не робот

Объединить два массива ключей и значений в объект с помощью подчеркивания

Для двух массивов, один с ключами, один со значениями:

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

Как бы вы преобразовали его в объект, , используя только методы underscore.js?

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

Я не ищу простой ответ на javascript (как это).

Я прошу об этом как о личном упражнении. Я думал, что у подчеркивания есть метод, который делает именно это, только чтобы узнать, что это не так, и это заставило меня задаться вопросом, можно ли это сделать. У меня есть ответ, но он включает в себя довольно много операций. Как вы это сделаете?

4b9b3361

Ответ 1

Что вам нужно использовать, это _. object метод подчеркивания js. Если метод объекта отсутствует в вашей версии underscore.js, вам придется вручную добавить к нему этот метод.

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>

Ответ 2

Как насчет:

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

Чтобы быть полным: другой подход может быть:

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

Для записи без подчеркивания вы можете расширить 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']);

См. jsfiddle

Ответ 3

Использование ES6:

let numbers = [1, 2, 3],
    names = ["John", "Mike", "Colin"];

let a = Object.assign({}, ...numbers.map((n, index) => ({[n]: names[index]})))

console.log(a);

Ответ 4

Я знаю, что вы попросили решения Underscore.js, но для этого вам это не нужно. Здесь oneliner с использованием оператора расширения ES7 и динамических клавиш.

keys.reduce((obj, k, i) => ({...obj, [k]: values[i] }), {})

Ответ 5

Самый чистый

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));

Ответ 6

var toObj = (ks, vs) => ks.reduce((o,k,i)=> {o[k] = vs[i]; return o;}, {});

var keys=['one', 'two', 'three'],
    values = [1, 2, 3];
var obj = toObj(keys, values);
console.log(obj);

Ответ 7

Учитывая, что это 4 года, и Lodash более или менее заменил Underscore, я решил поделиться этим решением с помощью Lodash:

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

Простой и чистый.

Ответ 8

То, что вы ищете, это zip-функция.

функция zip

Изменить: Он не создает объект, но он объединяет массив, создавая дополнительный массив

Нет функции, которая точно делает то, что вы хотите. Но вы можете использовать результат zip для создания своего объекта.

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];