【问题标题】:Push value into array by path in javascript在javascript中通过路径将值推送到数组中
【发布时间】:2017-01-24 14:07:47
【问题描述】:

我想知道是否有一种简单的方法可以在 JavaScript 中完成以下操作

我已有的代码:

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
    */
});

我想要的格式化对象如下所示:

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

还有一个问题:有没有一种简单的方法可以通过路径设置 formattedObject 中的值?

我的计划是用“.”分割路径,循环遍历它并在 formattedObject 中创建所需的层次结构。但是想知道是否有更好的方法来做到这一点?

【问题讨论】:

  • 顺便说一句,不需要那种类型的路径“projects.0.name”(带点“.”)。如果这样更容易的话,它也可以是其他一些符号......

标签: javascript arrays path


【解决方案1】:

通过使用Object.prototype.setNestedValue(),您可以动态设置深度嵌套对象的任何值。您只需要在参数中以正确的顺序提供属性名称和数组索引。最后一个参数是要设置的值。

让我们看看...

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));

您当然可以选择将Object.prototype.setNestedValue() 转换为普通函数并相应地调整您的代码。

【讨论】:

    【解决方案2】:

    您可以拆分路径并检查以下元素是否存在。如果不检查以下元素的数字并分配一个数组,否则将一个对象分配给新属性。然后返回属性的值。

    最后赋值。

    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);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-17
      • 2022-10-24
      • 2017-11-12
      • 1970-01-01
      • 1970-01-01
      • 2020-02-21
      • 2017-03-21
      • 2020-04-02
      相关资源
      最近更新 更多