遍历对象数组,通过 id 查找重复对象,将它们的值添加到单个对象中,react js

Loop through an array of objects, find duplicate objects by id, add their values in a single object, react js

我在 react class 组件中有一个生成属性的函数。因为我希望能够拥有重复的属性,所以我以可能的方式完成了它。但是,我希望将这些重复的属性组合为一个值,以便它可以在渲染函数中显示为单个 属性 具有更大的值,而不是 2 个具有更小值的属性。我如何根据以下代码实现此目的?

changePropertyState = () => {
  let rngProperties = []

  let maxProp = this.state.rarity.maxProperties;
  let minProp = this.state.rarity.minProperties;

  let rngCurrentPropAmount = Math.floor(Math.random() * (maxProp - minProp + 1) + minProp);

  // the actual properties for an item based on the array of properties
  for (let i = 0; i < rngCurrentPropAmount; i++) {
    let rngNum = Math.floor(Math.random() * (itemProperties.length))
    rngProperties.push(itemProperties[rngNum])
  }


  let proxyProperties = []

  // setting the values for each property based on the min and max of that property
  for (let j = 0; j < rngProperties.length; j++) {
    let rngValue = this.getRandomNumber(rngProperties[j].min, rngProperties[j].max);
    rngProperties[j].value = rngValue;
  
    // creating a proxy to store unique values for each property,
    let obj = {
      id: rngProperties[j].id,
      name: rngProperties[j].name,
      min: rngProperties[j].min,
      max: rngProperties[j].max,
      value: rngProperties[j].value
    }
    proxyProperties.push(obj);
  }

  //setState() has an inbuilt functionality for a callback function, in which we can console.log the newly changed state
  this.setState({
    properties: proxyProperties
  }, () => {
    // console.log('propF', this.state)
  });
}

以上代码的预期输出如下图所示。

我想要做的是组合称为(在本例中)“Area Damage”的 2 个属性,以便仅列出 1 属性,但值为 25(同样,在本例中)。

itemProperties 是具有以下结构的对象数组:

id: 1,
name: "intelligence",
min: 1,
max: 10,
value: 0

出于测试目的,rngCurrentPropAmount 可以替换为任何整数。这是要添加的属性数量。

逻辑是首先按 name 对数组进行分组,然后使用 reduce & summingvalue 合并它们。有点棘手但工作。希望这是所需要的。初始数组有 4 个元素,最后一个有两个。 value总结。

const arr = [
  {
    id: 1, name: "intelligence", min: 1, max: 10, value: 11
  },
  {
    id: 1, name: "intelligence", min: 1, max: 10, value: 4
  },
  {
    id: 2, name: "dexterity", min: 1, max: 10, value: 3
  },
  {
    id: 2, name: "dexterity", min: 1, max: 10, value: 8
  }
];

//group an array by property 
function groupBy(arr, property) {
  return arr.reduce(function(memo, x) {
    if (!memo[x[property]]) {
      memo[x[property]] = [];
    }
    memo[x[property]].push(x);
    return memo;
  }, {});
}

//group by name
const grouped = groupBy(arr, "name");
const keys = Object.keys(grouped);
var output = [];

//loop keys
keys.forEach(key => {
  //merge using reduce
  const out = grouped[key].reduce((acc, current) => {
    return {
      id: current.id,
      name: current.name,
      min: current.min,
      max: current.max,
      value: acc.value + current.value
    }
  });
  output.push(out);
});

console.log(output);