Я вырывал свои волосы, пытаясь объединить два многомерных массива объектов. У меня есть объектный массив «по умолчанию», а затем «определяемый пользователем» объектный массив.
Я могу, конечно, сделать это таким образом, чтобы код не мог использоваться повторно. Я хочу что-то, что я могу, независимо от грима, передать два массива объектов и сделать так, чтобы оно вернуло идеальное слияние.
var defaults = {
type: 1,
gui: {
width: 900,
height: 600,
margin: {
top: 50,
bottom: 200,
left: 100,
right: 50
},
mBg: ['#3f4c6b', '#606c88'],
mBgDir: 'vertical',
gBg: "#f9f9f9",
axlCol: '#000000',
axLw: 1,
xTitle: "X Title",
xFsz: 16,
xFnt: "Arial",
yTitle: "Y Title",
yFsz: 16,
yFnt: "Arial",
title: "Default Test",
titFsz: 16,
titFnt: "Arial",
labelFnt: "Arial",
labelSize: 13,
lblCol: "#ffffff",
plotLineCol: "#3f4c6b",
plotLineWidth: 1,
plotDots: true,
dotSize: 2,
dotCol: "#000000",
dotBorder: "#FF0000",
dotBrdSize: 0
}
}
var userdefined = {
data: 'qdbh',
ele: 'qgraph',
gui: {
xTitle: "Date/Time",
yTitle: "Testing",
title: "Last Day by Hour",
},
metrics: ['test', 'test1'],
caldep: []
}
Результат, который я ищу, таков:
var result = {
data: 'qdbh',
ele: 'qgraph',
type: 1,
metrics: ['test', 'test1'],
caldep: [],
gui: {
width: 900,
height: 600,
margin: {
top: 50,
bottom: 200,
left: 100,
right: 50
},
xTitle: "Date/Time",
yTitle: "Testing",
title: "Last Day by Hour",
mBg: ['#3f4c6b', '#606c88'],
mBgDir: 'vertical',
gBg: "#f9f9f9",
axlCol: '#000000',
axLw: 1,
xFsz: 16,
xFnt: "Arial",
yFsz: 16,
yFnt: "Arial",
titFsz: 16,
titFnt: "Arial",
labelFnt: "Arial",
labelSize: 13,
lblCol: "#ffffff",
plotLineCol: "#3f4c6b",
plotLineWidth: 1,
plotDots: true,
dotSize: 2,
dotCol: "#000000",
dotBorder: "#FF0000",
dotBrdSize: 0
}
}
Я также могу сделать это, если я включу ВСЕ доступные ключи в список значений по умолчанию. Как вы можете видеть, некоторые из пользовательских клавиш вообще не отображаются в настройках по умолчанию, так как они действительно должны быть определены пользователем.
Я чувствую, что я близко, но сигары пока нет. Я могу двигаться вперед, включив ВСЕ ключи по умолчанию, это работает. Тем не менее, я бы хотел лучшего решения, если это возможно.
Это то, что я имею до сих пор:
function getObjectKeys(obj) {
return Object.keys(obj);
}
function getObjectArrayType(obj) {
var type = Object.prototype.toString.call(obj);
if(type === "[object Object]") {
return "object";
} else if(type === "[object Array]") {
return "array";
} else {
return "unknown";
}
}
function mergeJsonObj(defaults, destination) {
var defKeys = getObjectKeys(defaults);
var result = {};
for (var d = 0; d < defKeys.length; d++) { //loop through object keys
//does default key exist in destination
if (destination[defKeys[d]] !== undefined) { //YES
//Is key an object
if (getObjectArrayType(destination[defKeys[d]]) === "object") { //YES
result[defKeys[d]] = mergeJsonObj(defaults[defKeys[d]], destination[defKeys[d]]);
} else {
result[defKeys[d]] = destination[defKeys[d]];
}
} else { //NO
result[defKeys[d]] = defaults[defKeys[d]]; //add default to graph spec
}
}
return result;
}
mergeJsonObj(defaults, userdefined);