将多个键的值相加并基于特定键合并为一个对象

huangapple go评论70阅读模式
英文:

Sum multiple keys and merge to one object based off a specific key

问题

以下是代码部分的翻译:

const total_sum_data = (arr, key, value) => {
  const map = new Map();
  for (const obj of arr) {
    const currSum = map.get(obj[key]) || 0;
    map.set(obj[key], currSum + obj[value]);
  }
  const res = Array.from(map, ([k, v]) => ({ [key]: k, [value]: v }));
  return res;
};

请注意,代码部分已经在你的消息中提供,不需要再次翻译。如果你需要有关代码的任何解释或进一步的帮助,请随时提问。

英文:

Let's say I have an array of objects and want to group these by a specified key: 'name', and sum all of their values into one object:

[
  { 
    name: "test1",
    value1: 100,
    value2: 100,
    value3: 100
  },
  { 
    name: "test1",
    value1: 100,
    value2: 100,
    value3: 100
  },
  { 
    name: "test2",
    value1: 200,
    value2: 100,
    value3: 100
  },
  { 
    name: "test2",
    value1: 200,
    value2: 100,
    value3: 100
  }, 
  { 
    name: "test3",
    value1: 100,
    value2: 100,
    value3: 100
  }
]

And the result I want would have this structure:

[
  {
    name: "test1",
    value1: 200,
    value2: 200,
    value3: 200
  },
  { 
    name: "test2",
    value1: 400,
    value2: 200,
    value3: 200
  },
  {
    name: "test3",
    value1: 100,
    value2: 100,
    value3: 100
  }
]

How would I go about doing this? I can currently get the sum of one key by using this method:

  const total_sum_data = (arr, key, value) => {
    const map = new Map();
    for (const obj of arr) {
      const currSum = map.get(obj[key]) || 0;
      map.set(obj[key], currSum + obj[value]);
    }
    const res = Array.from(map, ([k, v]) => ({ [key]: k, [value]: v }));
    return res;
  };

But not sure how to merge the results into one object with the specified key.

答案1

得分: 1

你可以使用数组的reduce方法将数组减少为累加器对象 (a),通过将每个对象解构为其 namevalues,然后在累加器对象中对每个 name 的所有值求和。然后,你只需要检索累加器的对象值以获得最终结果:

const result = Object.values(data.reduce((a, {name, ...values}) => {
  a[name] ??= { name };
  Object.entries(values).forEach(([key, value]) => {
    a[name][key] ??= 0;
    a[name][key] += value;
  });
  return a;
} , {}));

这个解决方案的时间复杂度为 O(n)。它会很好地处理添加新值(value4value5,...)和不是所有对象中都存在所有值的情况。

完整的代码段如下:

const data = [{
  name: "test1",
  value1: 100,
  value2: 100,
  value3: 100
}, {
  name: "test1",
  value1: 100,
  value2: 100,
  value3: 100
}, {
  name: "test2",
  value1: 200,
  value2: 100,
  value3: 100
}, {
  name: "test2",
  value1: 200,
  value2: 100,
  value3: 100
}, {
  name: "test3",
  value1: 100,
  value2: 100,
  value3: 100
}];

const result = Object.values(data.reduce((a, {name, ...values}) => {
  a[name] ??= { name };
  Object.entries(values).forEach(([key, value]) => {
    a[name][key] ??= 0;
    a[name][key] += value;
  });
  return a;
} , {}));

console.log(result);
英文:

You can reduce the array to an accumulator object (a) by destructuring each object into its name and values, and summing all the values for each name in the accumulator object. Then you just need to retrieve the accumulator's object values to get to your final result:

const result = Object.values(data.reduce((a, {name, ...values}) => {
  a[name] ??= { name };
  Object.entries(values).forEach(([key, value]) => {
    a[name][key] ??= 0;
    a[name][key] += value;
  });
  return a;
} , {}));

This solution has a time complexity of O(n). It will gracefully handle cases where new values are added (value4, value5, ...), and cases where not all values are present in all objects.


Complete snippet:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const data = [{
  name: &quot;test1&quot;,
  value1: 100,
  value2: 100,
  value3: 100
}, {
  name: &quot;test1&quot;,
  value1: 100,
  value2: 100,
  value3: 100
}, {
  name: &quot;test2&quot;,
  value1: 200,
  value2: 100,
  value3: 100
}, {
  name: &quot;test2&quot;,
  value1: 200,
  value2: 100,
  value3: 100
}, {
  name: &quot;test3&quot;,
  value1: 100,
  value2: 100,
  value3: 100
}];

const result = Object.values(data.reduce((a, {name, ...values}) =&gt; {
  a[name] ??= { name };
  Object.entries(values).forEach(([key, value]) =&gt; {
    a[name][key] ??= 0;
    a[name][key] += value;
  });
  return a;
} , {}));

console.log(result);

<!-- end snippet -->

答案2

得分: 0

以下是代码的翻译部分:

例如

    const total_sum_data = (arr, key) => {
      const map = new Map();
      for (const obj of arr) {
        const groupKey = obj[key];
        if (!map.has(groupKey)) {
          map.set(groupKey, { [key]: groupKey });
        }
        const currObj = map.get(groupKey);
        Object.keys(obj).forEach(k => {
          if (k !== key) {
            currObj[k] = (currObj[k] || 0) + obj[k];
          }
        });
      }
      return Array.from(map.values());
    };

    console.log(total_sum_data(arr,"name"));
英文:

For example:

const total_sum_data = (arr, key) =&gt; {
  const map = new Map();
  for (const obj of arr) {
    const groupKey = obj[key];
    if (!map.has(groupKey)) {
      map.set(groupKey, { [key]: groupKey });
    }
    const currObj = map.get(groupKey);
    Object.keys(obj).forEach(k =&gt; {
      if (k !== key) {
        currObj[k] = (currObj[k] || 0) + obj[k];
      }
    });
  }
  return Array.from(map.values());
};

console.log(total_sum_data(arr,&quot;name&quot;)); 

答案3

得分: 0

使用 Map 和 reduce 可以实现这个功能。

在使用 Map 的情况下,代码如下:

const map = new Map();

for (const item of data) {
  if (!map.has(item.name)) {
    map.set(item.name, {
      name: item.name,
      value1: item.value1,
      value2: item.value2,
      value3: item.value3
    });
  } else {
    map.get(item.name).value1 += item.value1;
    map.get(item.name).value2 += item.value2;
    map.get(item.name).value3 += item.value3;
  }
}
console.log(Array.from(map.values()));

而在使用 reduce 的情况下,可以这样实现:

const groupedSum = data.reduce((acc, curr) => {
  const objIndex = acc.findIndex(obj => obj.name === curr.name);
  if (objIndex === -1) {
    acc.push({ name: curr.name, value1: curr.value1, value2: curr.value2, value3: curr.value3 });
  } else {
    acc[objIndex].value1 += curr.value1;
    acc[objIndex].value2 += curr.value2;
    acc[objIndex].value3 += curr.value3;
  }
  return acc;
}, []);
console.log(groupedSum);

希望这些对你有帮助。

英文:

It can be achieved using Map and reduce.

while using Map here is a code:

const map = new Map();

for (const item of data) {
  if (!map.has(item.name)) {
    map.set(item.name, {
      name: item.name,
      value1: item.value1,
      value2: item.value2,
      value3: item.value3
    });
  } else {
    map.get(item.name).value1 += item.value1;
    map.get(item.name).value2 += item.value2;
    map.get(item.name).value3 += item.value3;
  }
}
console.log(Array.from(map.values()));

and while using reduce it can be done like this

const groupedSum = data.reduce((acc, curr) =&gt; {
  const objIndex = acc.findIndex(obj =&gt; obj.name === curr.name);
  if (objIndex === -1) {
    acc.push({ name: curr.name, value1: curr.value1, value2: curr.value2, value3: curr.value3 });
  } else {
    acc[objIndex].value1 += curr.value1;
    acc[objIndex].value2 += curr.value2;
    acc[objIndex].value3 += curr.value3;
  }
  return acc;
}, []);
console.log(groupedSum);

答案4

得分: 0

希望以下逻辑能帮助您:

let array = [
  { 
    name: "test1",
    value1: 100,
    value2: 100,
    value3: 100
  },
  { 
    name: "test1",
    value1: 100,
    value2: 100,
    value3: 100
  },
  { 
    name: "test2",
    value1: 200,
    value2: 100,
    value3: 100
  },
  { 
    name: "test2",
    value1: 200,
    value2: 100,
    value3: 100
  }, 
  { 
    name: "test3",
    value1: 100,
    value2: 100,
    value3: 100
  },
]

let reduceArr = array.reduce((prev, next) =>{
    if (next.name in prev) {
      prev[next.name].value1 += next.value1;
      prev[next.name].value2 += next.value2;
      prev[next.name].value3 += next.value3;
    } else {
       prev[next.name] = next;
    }
    return prev;
  }, {});

let result = Object.values(reduceArr);

console.log(result)

请注意,我已经移除了HTML标记以及HTML注释,只保留了JavaScript代码。

英文:

Hope below logic will help you

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let array = [
  { 
    name: &quot;test1&quot;,
    value1: 100,
    value2: 100,
    value3: 100
  },
  { 
    name: &quot;test1&quot;,
    value1: 100,
    value2: 100,
    value3: 100
  },
  { 
    name: &quot;test2&quot;,
    value1: 200,
    value2: 100,
    value3: 100
  },
  { 
    name: &quot;test2&quot;,
    value1: 200,
    value2: 100,
    value3: 100
  }, 
  { 
    name: &quot;test3&quot;,
    value1: 100,
    value2: 100,
    value3: 100
  },

]


let reduceArr = array.reduce((prev, next) =&gt;{
    if (next.name in prev) {
      prev[next.name].value1 += next.value1;
      prev[next.name].value2 += next.value2;
      prev[next.name].value3 += next.value3;
    } else {
       prev[next.name] = next;
    }
    return prev;
  }, {});

let result = Object.values(reduceArr);


console.log(result)

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月8日 13:50:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75381808.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定