[removed] Determine unknown array length and map dynamically

后端 未结 5 741
深忆病人
深忆病人 2021-02-08 11:01

Going to do my best at explaining what I am trying to do.

I have two models, mine and an api response I am receiving. When the items api response comes in, I need to map

5条回答
  •  臣服心动
    2021-02-08 11:13

    I have borrowed earlier answer and made improvements so as to solve both your examples and this should be generic. Though if you plan to run this sequencially with 2 sets of inputs, then the behavior will be as I have outlined in my comments to your original question.

        var apiObj = {
        items: [{
            name: "Hammer",
            skus: [{
                num: "12345qwert"
            }]
        }, {
            name: "Bike",
            skus: [{
                num: "asdfghhj"
            }, {
                num: "zxcvbn"
            }]
        }, {
            name: "Fork",
            skus: [{
                num: "0987dfgh"
            }]
        }]
    };
    
    var myObj = { //Previously has values
        storeName: "",
        items: [{
            uniqueName: ""
        }],
        outputModel: {
            items: [{
                name: "Hammer"
            }]
        }
    };
    
    /** Also works with this **
    var myPath = "outputModel.items[].uniqueName";
    var apiPath = "items[].name";
    */
    var myPath = "outputModel.items[].sku";
    var apiPath = "items[].skus[].num";
    
    function make_accessor(program) {
    
        return function (obj, callback) {
            (function do_segment(obj, segments) {
                var start = segments.shift() // Get first segment
                var pieces = start.match(/(\w+)(\[\])?/); // Get name and [] pieces
                var property = pieces[1];
                var isArray = pieces[2]; // [] on end
                obj = obj[property]; // drill down
    
                if (!segments.length) { // last segment; callback
                    if (isArray) {
                        return obj.forEach(callback);
                    } else {
                        return callback(obj);
                    }
                } else { // more segments; recurse
                    if (isArray) { // array--loop over elts
                        obj.forEach(function (elt) {
                            do_segment(elt, segments.slice());
                        });
                    } else {
                        do_segment(obj, segments.slice()); // scalar--continue
                    }
                }
            })(obj, program.split('.'));
        };
    }
    
    function make_inserter(program) {
    
        return function (obj, value) {
            (function do_segment(obj, segments) {
                var start = segments.shift() // Get first segment
                var pieces = start.match(/(\w+)(\[\])?/); // Get name and [] pieces
                var property = pieces[1];
                var isArray = pieces[2]; // [] on end
                if (segments.length) { // more segments
                    if (!obj[property]) {
                        obj[property] = isArray ? [] : {};
                    }
                    do_segment(obj[property], segments.slice());
                } else { // last segment
                    if (Array.isArray(obj)) {
                        var addedInFor = false;
                        for (var i = 0; i < obj.length; i++) {
                            if (!(property in obj[i])) {
                                obj[i][property] = value;
                                addedInFor = true;
                                break;
                            }
                        }
                        if (!addedInFor) {
                            var entry = {};
                            entry[property] = value;
                            obj.push(entry);
                        }
                    } else obj[property] = value;
                }
            })(obj, program.split('.'));
        };
    }
    
    access = make_accessor(apiPath);
    insert = make_inserter(myPath);
    
    access(apiObj, function (val) {
        insert(myObj, val);
    });
    
    console.log(myObj);
    

提交回复
热议问题