Объединение двух массивов для создания объекта 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).
Я не понимаю, как объединить имена столбцов со строками для создания массива объектов. Тот факт, что "строки" содержит массивы, особенно запутан.
Ответы
Ответ 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
}, {});
});
}