Объединение двух массивов для формирования объекта JavaScript - PullRequest
20 голосов
/ 13 февраля 2012

У меня есть два массива:

var columns = ["Date", "Number", "Size", "Location", "Age"];

var rows = [["2001", "5", "Big", "Sydney", "25"],["2005", "2", "Med", "Melbourne", "50"],["2012", "20", "Huge", "Brisbane", "80"]];

Я пытаюсь объединить их в объект javascript для каждого элемента в массиве строк.После этого я хочу поместить каждый объект в новый массив.

Например:

var newarray = [];

//'thing' should be the same structure for each row item
var thing = {
   "Date" : "2001",
   "Number" : "5",
   "Size":"Big",
   "Location":"Sydney",
   "Age":"25"
}

newarray.push(thing);

Я могу сделать это, когда знаю имена столбцов, но мне нужно уметьхранить данные таким образом, когда имя столбца неизвестно - т.е. на основе индексов массива столбцов.

Я пробовал это так раньше:

       for(var y = 0; y < rows.length; y++){

            for(var i = 0; i < columns.length; i++){
                 thing[columns[i]] = rows[i][i];
           }
              newarray.push(thing)
       }

Только код вышеснова и снова сохранял первый элемент (в соответствии с rows.length).

Я не понимаю, как объединить имена столбцов со строками для создания массива объектов.Тот факт, что «строки» содержат массивы, особенно сбивает с толку ..

Ответы [ 9 ]

23 голосов
/ 13 февраля 2012

Вы можете сделать это более ориентированным на данные способом:

var columns = ["Date", "Number", "Size", "Location", "Age"];

var rows = [
  ["2001", "5", "Big", "Sydney", "25"],
  ["2005", "2", "Med", "Melbourne", "50"],
  ["2012", "20", "Huge", "Brisbane", "80"]
];

var result = rows.map(function(row) {
  return row.reduce(function(result, field, index) {
    result[columns[index]] = field;
    return result;
  }, {});
});

Таким образом, вам не придется иметь дело с временными массивами.

Если ваш код должен работать и в древних браузерах, я рекомендую взглянуть на underscore.js для использования map + reduce.

9 голосов
/ 13 февраля 2012

Создайте новый объект thing в начале каждой итерации внешнего цикла. Если вы этого не сделаете, то каждый раз, когда вы говорите thing[columns[i]], вы перезаписываете свойства одного и того же объекта, а когда вы помещаете его в newarray, вы получаете массив, полный ссылок на тот же объект . Кроме того, внутри цикла убедитесь, что вы правильно настроили индексы (в настоящее время вы получаете [i][i] вместо [y][i]):

var newarray = [],
    thing;

for(var y = 0; y < rows.length; y++){
    thing = {};
    for(var i = 0; i < columns.length; i++){
        thing[columns[i]] = rows[y][i];
    }
    newarray.push(thing)
}

«Тот факт, что« строки »содержат массивы, особенно сбивает с толку ..»

Для ваших примеров данных rows.length будет 3, а rows[0] - массив:

["2001", "5", "Big", "Sydney", "25"]

rows[0][3] - это "Сидней".

Используя это в качестве примера, вы сможете увидеть, что rows[y][i] даст вам для каждого значения y и i ...

4 голосов
/ 01 ноября 2012

Если вы используете Underscore.js, есть _.object(list, [values])

А вот как это реализовано:

_.object = function(list, values) {
  if (list == null) return {};
  var result = {};
  for (var i = 0, length = list.length; i < length; i++) {
    if (values) {
      result[list[i]] = values[i];
    } else {
      result[list[i][0]] = list[i][1];
    }
  }
  return result;
};
3 голосов
/ 18 сентября 2013

Использование функционала будет похоже на nnnnnn, но с незначительной коррекцией

var columns = ["Date", "Number", "Size", "Location", "Age"];

var rows = [
  ["2001", "5", "Big", "Sydney", "25"],
  ["2005", "2", "Med", "Melbourne", "50"],
  ["2012", "20", "Huge", "Brisbane", "80"]
];

var result = rows.map(function(row) {
  return row.reduce(function(result, field, index) {
    result[columns[index]] = field;
    return result
  }, {});
});
1 голос
/ 11 декабря 2017

Вы можете использовать эту функцию после кода ES6:

const assemblyData = ( columns, rows) => {
   return rows.map((row) => {
       return row.reduce((res, field, index) => {
         res[columns[index]] = field;
         return res
       }, {});
  });
}

// short version
const assemblyDataMin = (columns, rows) =>
  rows.map(row =>
    row.reduce((res, field, index) => {
      res[columns[index]] = field;
      return res;
    }, {})
  );

Ссылка на примеры

1 голос
/ 13 февраля 2012

Вам необходимо указать правильный ряд.Вы используете столбец.Заменить rows[i][i] на rows[y][i].Кроме того, похоже, что вы снова и снова используете один и тот же объект thing.Вместо этого вы должны определять его заново каждую итерацию в массиве (var thing = {};).

   var newarray = [];
   for (var y = 0; y < rows.length; y++) {
       var thing = {};
       for (var i = 0; i < columns.length; i++) {
           thing[columns[i]] = rows[y][i];
       }
       newarray.push(thing);
   }
0 голосов
/ 29 ноября 2016

я думаю, что мое решение - решить вашу проблему

код:

    var keys = columns,
        values = rows,
        finalarray = [];

        values.forEach((data,index) =>{
            var objJSON = new Object();
            for (i = 0; i < keys.length; i++) {
                objJSON[keys[i]] = data[i];
               }
            finalarray.push(objJSON);  
        });

ответ:

console.log(finalarray)

[{
   "Date" : "2001",
   "Number" : "5",
   "Size":"Big",
   "Location":"Sydney",
   "Age":"25"
},
...
}]
0 голосов
/ 29 августа 2015

Вместо зацикливания по всей таблице вы также можете использовать массив столбцов для генерации класса Row (используя defineProperty ), а затем использовать этот класс строк, чтобы обернуть массивы строк в массиве строк.Результирующий массив объектов Row затем привязывается к исходному массиву строк, так что изменения в одном отражаются в другом.В зависимости от вашего варианта использования, это может быть полезным или проблемой.Рабочий пример приведен во фрагменте ниже.

var columns = ["Date", "Number", "Size", "Location", "Age"];

var rows = [
  ["2001", "5", "Big", "Sydney", "25"],
  ["2005", "2", "Med", "Melbourne", "50"],
  ["2012", "20", "Huge", "Brisbane", "80"]
];

var table = create_table(columns, rows);

// 
for (var i = 0; i<table.length; i++) {
  document.writeln("The thing in " + table[i].Location + " is " + table[i].Size + "<br/>");
}

// The rows in table are still tied to those in the rows variable
table[0].Size = "Small";
document.writeln(JSON.stringify(rows[0]));

function create_table(columns, rows) {
  // Create a Row class with the given columns
  for (var i=0; i<columns.length; i++) {
    var c = columns[i];
    Object.defineProperty(Row.prototype, c, {
      enumerable: true, 
      get: getter(i),
      set: setter(i),
    });
  }
  // Wrap the rows in row objects and return the resulting array
  var r = new Array(rows.length);
  for (var i=0; i<rows.length; i++) {
    r[i] = new Row(rows[i]);
  }
  return r;

  function Row(row) { this._ = row; }

  // Generators for the getter and setter functions, with variable i stored in a closure.
  function getter(i) {
    return function(){
      return this._[i];
    };
  }
  function setter(i) {
    return function(val){
      return this._[i] = val;
    };
  }
}
0 голосов
/ 13 февраля 2012

вам просто нужно сбросить thing

 for(var y = 0; y < rows.length; y++){
   for(var i = 0; i < columns.length; i++){
       thing[columns[i]] = rows[y][i];
   }

   newarray.push(thing);
   thing = {};    
 }

см. Обновление: скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...