在 Nuxtjs 中使用 reduce 时更改了源数据

source data changed when using reduce in Nuxtjs

我的代码:

export default {
  data() {
    return {
      services: [],
      mydata: [
        {id: 1, count: 102, price: 0.1},
        {id: 1, count: 0, price: 0.09},
        {id: 2, count: 20, price: 0.5},
      ]
    };
  },
  mounted() {
    this.start();
  },
  methods: {
    start() {
      this.services = this.mydata.reduce((acc, curr) => {
        let item = acc.find((obj) => obj.id == curr.id);
        if (item) {
          item.count += curr.count;
          item.price = item.price > curr.price ? curr.price : item.price;
        } else {
          acc.push(curr);
        }
        return acc;
      }, []);
    },
  },
};

我想合并 mydata 数组并保存到 services 变量中。我希望 count 是总和,而较低的 price 被选择用于新对象。 (我用 reduce 来做这个)

我的预期services

[
        {id: 1, count: 102, price: 0.09},
        {id: 2, count: 20, price: 0.5},
]

它有效,但源数据(mydata)被操作并转换为:(第一个对象的 price 被操作并转换为 0.09,之前是 0.1)

[
        {id: 1, count: 102, price: 0.09},
        {id: 1, count: 0, price: 0.09},
        {id: 2, count: 20, price: 0.5}
]

为什么会这样?

会发生什么?

你实际上是在修改 mydata

当您在数组中找到对象时会发生这种情况:

let item = acc.find((obj) => obj.id == curr.id);

然后修改

item.count += curr.count;
item.price = item.price > curr.price ? curr.price : item.price;

为什么会这样?

在JavaScript中我们有两种数据类型。

  • 原始类型(BooleanStringNumbernullundefined)并且它们通过值传递.
  • ArrayFunctionObject 通过引用

在你的例子中,你在数组中找到一些对象,然后修改它的属性,这意味着你正在对引用进行操作。

怎么做?

  1. 如果你有基本类型的数组,你可以使用例如展开运算符进行浅拷贝:
let arr = ['a', 'b', 'c']
[...arr].reduce()
  1. 如果你有复杂类型的数组,你需要编写自定义函数或使用一些为你实现它的库,比如 Lodash or Ramda