在嵌套对象数组中查找并更新值

6

我有一个对象数组如下:

products = [
  {
    id: 1,
    title: "Product 1",
    specifications: {
      price: 1.55,
      discount: 15,
      attributes: [
        {
          l1: 100,
          l2: 80
          height:200,
          weight: 15,
          parameters: [
            {
              id: 199199 // this is how I identify the parameter
              size: 185 // this is what I want to change
            }, ... 
          ]    
        }, ...
      ]

    }
  }, ...
]

我有一个参数变化的数组,例如:当product.specifications.attributes.parameters.id == 199199时,将大小更改为189。

我想在不展平任何元素的情况下完成此操作,因为它们是Vue.js数据结构的一部分,展平会破坏响应性。

我应该如何做?我可以使用Underscore或lo-dash。

3个回答

3

这看起来很丑,但它是有效的:

为了使其更加动态化,让我们使用变量:identifier 将成为你的“199199”值,而 new_size 则为“189”值。

methods: {
    updateRecord: function(identifier, new_size) {
        this.products.map(function(product) {   
            product.specifications.attributes.map(function(attribute)           {
                attribute.parameters.map(function(parameter) {
                    if (parameter.id == identifier) parameter.size = new_size;
                })
            });
        });
    }
}

这是一个可工作的代码片段:https://jsfiddle.net/crabbly/eL7et9e8/


非常好。由于参数ID是唯一的,我在改变大小后应该中断吗?根据https://dev59.com/jXVC5IYBdhLWcg3wykaj - Nick M
运行了一个测试,屏幕上显示了大约5000个产品。我选择了你的答案,因为它似乎比stasovlas提交的答案更新所有数据所需的时间少几毫秒。在更新后尝试打破循环,这将节省更多的循环,因为每个产品只会显示一次。 - Nick M
@NickM 很不幸,Array.prototype.map 没有内置的 break 选项。除非你有极大数量的项目,否则你可能看不到太大的性能差异。 - crabbly

1
_.forEach(products, function(product) {
    _.forEach(_.get(product, 'specifications.attributes', []), function(attribute) {
        _.set(_.find(attribute.parameters, {id: 199199}), 'size', 189);
    });
});

如果一个产品没有“attributes”键,它不会抛出异常吗? - Nick M
另外,.map 会产生一个新的数组,这不是我想要的...这能否通过一系列的 .selects 和 .extend({ size: 189 }) 重写或类似的方法来实现“原地”编辑值? - Nick M

0

我认为你需要的是下划线库中的findIndex()方法 - http://underscorejs.org/#findIndex。一旦找到你想要应用更改的数组元素(将嵌套的id与你要查找的内容进行比较),然后就可以对该特定元素进行更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接