Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 431
AndVla Avatar asked Mar 01 '26 00:03

AndVla


2 Answers

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);
like image 128
Nina Scholz Avatar answered Mar 03 '26 12:03

Nina Scholz


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.

like image 41
Redu Avatar answered Mar 03 '26 13:03

Redu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!