Многоразовая функция для объединения массивов многомерных объектов в простой JavaScript - PullRequest
0 голосов
/ 23 октября 2019

Я вырывал свои волосы, пытаясь объединить два многомерных массива объектов. У меня есть объектный массив «по умолчанию», а затем «определяемый пользователем» объектный массив.

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

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...