简体   繁体   中英

Push value into array by path in javascript

I'm wondering if there is an easy way to complete the following in JavaScript

The code that I already have:

var formattedObject = {
    "id": "1"
};
var mapping = {
    "name": "name",
    "project": "projects.0.name"
};
$.each(mapping, function(path, fieldName) {
    fieldValue = $('form input[name="' + fieldName + '"]').val();
    /*
        Here I need to push a field value into array by path
    */
});

What I want my formatted object looks like:

var formattedObject = {
    "id": "1",
    "name": "Object name", //comes from input field
    "projects": [{
        "name": "My project name" //comes from input field
    }]
};

And the question: Is there an easy way to set the value in formattedObject by path?

My plan is to split the path by ".", loop through it and create the needed hierarchy inside the formattedObject. But wondering if there is a better way for doing it?

You could split the path and make a check if the following element exist. If not check the following element for number and assign the an array, otherwise an object to the new property. Return then the value of the property.

At the end assign the value.

 function setValue(object, path, value) { var fullPath = path.split('.'), way = fullPath.slice(), last = way.pop(); way.reduce(function (r, a, i, aa) { function isNumber(v) { return String(+v) === v; } return r[a] = r[a] || isNumber(fullPath[i + 1]) ? [] : {}; }, object)[last] = value; } var formattedObject = { id: "1" }, mapping = { name: "name", project: "projects.0.name" }; setValue(formattedObject, mapping.name, 'xyz'); setValue(formattedObject, mapping.project, 42); console.log(formattedObject); 

By utilizing Object.prototype.setNestedValue() you can dynamically set any value of a deeply nested object. All you need is to provide the property name and array indices in correct order in the arguments. The last argument would be the value to be set.

Lets see...

 Object.prototype.setNestedValue = function(...a) { a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1)) : (this[a[0]] = typeof a[1] === "string" ? {} : new Array(a[1]), this[a[0]].setNestedValue(...a.slice(1))) : this[a[0]] = a[1]; return this; }; var formattedObject = { "id": "1", "name": "Object name", //comes from input field "projects": [{ "name": "My project name" //comes from input field }] }; console.log(JSON.stringify(formattedObject.setNestedValue("name","New Name"),null,4)); console.log(JSON.stringify(formattedObject.setNestedValue("projects",0,"name","New Project Name"),null,4)); 

You might of course chose to convert Object.prototype.setNestedValue() into normal function and adjust your code accordingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM