Объединение двух массивов для создания объекта javascript - программирование
Подтвердить что ты не робот

Объединение двух массивов для создания объекта javascript

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

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

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

4b9b3361

Ответ 1

Создайте новый объект 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...

Ответ 2

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

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.

Ответ 3

Если вы используете 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;
};

Ответ 4

Использование функционала будет похоже на 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
  }, {});
});

Ответ 5

Вам нужно указать правую строку. Вы используете столбец. Замените 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);
   }

Ответ 6

вам просто нужно reset 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 = {};    
 }

см. обновление: fiddle

Ответ 7

Вместо того, чтобы перебирать всю таблицу, вы также можете использовать массив столбцов для создания класса 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;
    };
  }
}

Ответ 8

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

код:

    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"
},
...
}]

Ответ 9

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

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