结合不同的方法来计数嵌套列表中的元素

发布于 2025-01-19 13:29:39 字数 1831 浏览 1 评论 0原文

我有一个嵌套对象,我不仅想计算每个 point_name 出现的次数,而且还想计算每个 point_name 属于多少个类别。

dat = [
  {name: "Category 1", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "C"} ]},
  {name: "Category 2", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "D"} ]},
  {name: "Category 3", points: [ {point_name: "A"}, {point_name: "D"}, {point_name: "E"} ]},
  {name: "Category 4", points: [ {point_name: "F"}, {point_name: "G"}, {point_name: "C"}, {point_name: "G"} ]},
  {name: "Category 5", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "H"}, {point_name: "H"} ]}
]

所需输出

[
  {name: "A", count: 4, categories: 4},
  {name: "B", count: 3, categories: 3},
  {name: "C", count: 2, categories: 2},
  {name: "D", count: 2, categories: 2},
  {name: "G", count: 2, categories: 1},
  {name: "H", count: 2, categories: 1},
  {name: "E", count: 1, categories: 1},
  {name: "F", count: 1, categories: 1}
]

到目前为止我已经尝试过,

我使用嵌套 for 循环来获取所有 point_names,这样我就可以在 reduce 中使用它来计算每个 point_name 的次数发生了,但是我无法弄清楚如何计算每个 point_name 所属的类别数量。

  // double loop to get each point name
  let counts = []
  for (let i = 0; i < dat.length; i++) {
    for (let j = 0; j < dat[i].points.length; j++) {
      counts.push(dat[i].points[j].point_name)
    }
  }

  // count their unique values
  let uniques = counts.reduce((acc, val) => {
     acc[val] = acc[val] === undefined ? 1 : acc[val] += 1;
  return acc;
  }, {});

  // turn into array of objects
  return  Array(Object.keys(uniques).length)
                         .fill()
                         .map((x, i) => ({ name: Object.keys(uniques)[i], count: Object.values(uniques)[i] }))

任何帮助表示赞赏!

I have a nested object where I not only want to count the number of times each point_name occurs, but I also want to count how many categories each point_name is in.

dat = [
  {name: "Category 1", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "C"} ]},
  {name: "Category 2", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "D"} ]},
  {name: "Category 3", points: [ {point_name: "A"}, {point_name: "D"}, {point_name: "E"} ]},
  {name: "Category 4", points: [ {point_name: "F"}, {point_name: "G"}, {point_name: "C"}, {point_name: "G"} ]},
  {name: "Category 5", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "H"}, {point_name: "H"} ]}
]

Desired Output

[
  {name: "A", count: 4, categories: 4},
  {name: "B", count: 3, categories: 3},
  {name: "C", count: 2, categories: 2},
  {name: "D", count: 2, categories: 2},
  {name: "G", count: 2, categories: 1},
  {name: "H", count: 2, categories: 1},
  {name: "E", count: 1, categories: 1},
  {name: "F", count: 1, categories: 1}
]

What I've tried so far

I used a nested for loop to get all the point_names so I can use that in a reduce to count how many times each point_name occurs, but I can't figure out how to also count the number of categories each point_name is in.

  // double loop to get each point name
  let counts = []
  for (let i = 0; i < dat.length; i++) {
    for (let j = 0; j < dat[i].points.length; j++) {
      counts.push(dat[i].points[j].point_name)
    }
  }

  // count their unique values
  let uniques = counts.reduce((acc, val) => {
     acc[val] = acc[val] === undefined ? 1 : acc[val] += 1;
  return acc;
  }, {});

  // turn into array of objects
  return  Array(Object.keys(uniques).length)
                         .fill()
                         .map((x, i) => ({ name: Object.keys(uniques)[i], count: Object.values(uniques)[i] }))

Any help appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

百变从容 2025-01-26 13:29:39

转换

[ {name: "Category 1", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "C"} ]}
, {name: "Category 2", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "D"} ]}
, {name: "Category 3", points: [ {point_name: "A"}
                               , {point_name: "D"}
                               , {point_name: "E"} ]}
, {name: "Category 4", points: [ {point_name: "F"}
                               , {point_name: "G"}
                               , {point_name: "C"}
                              ,  {point_name: "G"} ]}
, {name: "Category 5", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "H"}
                               , {point_name: "H"} ]}]

[ {name: 'A', category: 'Category 1'}
, {name: 'B', category: 'Category 1'}
, {name: 'C', category: 'Category 1'}
, {name: 'A', category: 'Category 2'}
, {name: 'B', category: 'Category 2'}
, {name: 'D', category: 'Category 2'}
, {name: 'A', category: 'Category 3'}
, {name: 'D', category: 'Category 3'}
, {name: 'E', category: 'Category 3'}
, {name: 'F', category: 'Category 4'}
, {name: 'G', category: 'Category 4'}
, {name: 'C', category: 'Category 4'}
, {name: 'G', category: 'Category 4'}
, {name: 'A', category: 'Category 5'}
, {name: 'B', category: 'Category 5'}
, {name: 'H', category: 'Category 5'}
, {name: 'H', category: 'Category 5'}]

With

dat.flatMap(({name: category, points}) =>
  points.map(p =>
    ({name: p.point_name, category})))

然后减少 with:

….reduce((acc, p) => {
  acc[p.name] ??= [0, new Set];
  acc[p.name][0] += 1;
  acc[p.name][1].add(p.category);
  return acc;
}, {}))

这给你这个:

在此处输入图像描述

将所有内容放在一起:

console.log(

Object
  .entries(
    dat
      .flatMap(({name: category, points}) =>
        points.map(p =>
          ({name: p.point_name, category})))
      .reduce((acc, p) => {
        acc[p.name] ??= [0, new Set];
        acc[p.name][0] += 1;
        acc[p.name][1].add(p.category);
        return acc;
      }, {}))
  .map(([name, [count, categories]]) =>
    ({name, count, categories: categories.size}))

)
<script>
var dat =
[ {name: "Category 1", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "C"} ]}
, {name: "Category 2", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "D"} ]}
, {name: "Category 3", points: [ {point_name: "A"}
                               , {point_name: "D"}
                               , {point_name: "E"} ]}
, {name: "Category 4", points: [ {point_name: "F"}
                               , {point_name: "G"}
                               , {point_name: "C"}
                              ,  {point_name: "G"} ]}
, {name: "Category 5", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "H"}
                               , {point_name: "H"} ]}]
</script>

Transform

[ {name: "Category 1", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "C"} ]}
, {name: "Category 2", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "D"} ]}
, {name: "Category 3", points: [ {point_name: "A"}
                               , {point_name: "D"}
                               , {point_name: "E"} ]}
, {name: "Category 4", points: [ {point_name: "F"}
                               , {point_name: "G"}
                               , {point_name: "C"}
                              ,  {point_name: "G"} ]}
, {name: "Category 5", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "H"}
                               , {point_name: "H"} ]}]

Into

[ {name: 'A', category: 'Category 1'}
, {name: 'B', category: 'Category 1'}
, {name: 'C', category: 'Category 1'}
, {name: 'A', category: 'Category 2'}
, {name: 'B', category: 'Category 2'}
, {name: 'D', category: 'Category 2'}
, {name: 'A', category: 'Category 3'}
, {name: 'D', category: 'Category 3'}
, {name: 'E', category: 'Category 3'}
, {name: 'F', category: 'Category 4'}
, {name: 'G', category: 'Category 4'}
, {name: 'C', category: 'Category 4'}
, {name: 'G', category: 'Category 4'}
, {name: 'A', category: 'Category 5'}
, {name: 'B', category: 'Category 5'}
, {name: 'H', category: 'Category 5'}
, {name: 'H', category: 'Category 5'}]

With

dat.flatMap(({name: category, points}) =>
  points.map(p =>
    ({name: p.point_name, category})))

Then reduce with:

….reduce((acc, p) => {
  acc[p.name] ??= [0, new Set];
  acc[p.name][0] += 1;
  acc[p.name][1].add(p.category);
  return acc;
}, {}))

Which gives you this:

enter image description here

Putting everything together:

console.log(

Object
  .entries(
    dat
      .flatMap(({name: category, points}) =>
        points.map(p =>
          ({name: p.point_name, category})))
      .reduce((acc, p) => {
        acc[p.name] ??= [0, new Set];
        acc[p.name][0] += 1;
        acc[p.name][1].add(p.category);
        return acc;
      }, {}))
  .map(([name, [count, categories]]) =>
    ({name, count, categories: categories.size}))

)
<script>
var dat =
[ {name: "Category 1", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "C"} ]}
, {name: "Category 2", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "D"} ]}
, {name: "Category 3", points: [ {point_name: "A"}
                               , {point_name: "D"}
                               , {point_name: "E"} ]}
, {name: "Category 4", points: [ {point_name: "F"}
                               , {point_name: "G"}
                               , {point_name: "C"}
                              ,  {point_name: "G"} ]}
, {name: "Category 5", points: [ {point_name: "A"}
                               , {point_name: "B"}
                               , {point_name: "H"}
                               , {point_name: "H"} ]}]
</script>

难以启齿的温柔 2025-01-26 13:29:39

您需要的是一个哈希表,用于保存遇到的每个类别的计数和数量。像这样的东西。

var data = [
      {name: "Category 1", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "C"} ]},
      {name: "Category 2", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "D"} ]},
      {name: "Category 3", points: [ {point_name: "A"}, {point_name: "D"}, {point_name: "E"} ]},
      {name: "Category 4", points: [ {point_name: "F"}, {point_name: "G"}, {point_name: "C"}, {point_name: "G"} ]},
      {name: "Category 5", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "H"}, {point_name: "H"} ]}
    ];
    var hashTable = {};
    data.forEach(d=>{
     var points = d.points;
     points.forEach(k=>{
       if(hashTable[k.point_name]){
       hashTable[k.point_name] ={
          count: hashTable[k.point_name].count +1,
          cat: [...hashTable[k.point_name].cat, d.name],
          categoryCount: hashTable[k.point_name].cat.includes(d.name) ? hashTable[k.point_name].categoryCount : hashTable[k.point_name].categoryCount+1
      } 
      
       }else{
          hashTable[k.point_name]  = {count: 1,
          cat: [d.name],
          categoryCount:1
        }}
     })
    })
// console.log(hashTable);
var res = [];
Object.keys(hashTable).forEach(o=>{
 res.push({
   name: o,
   count: hashTable[o].count,
   categories: hashTable[o].categoryCount
 })
});

console.log(res)

What you need is a hashtable that keeps the count and cunt of each category encountered. Something like this.

var data = [
      {name: "Category 1", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "C"} ]},
      {name: "Category 2", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "D"} ]},
      {name: "Category 3", points: [ {point_name: "A"}, {point_name: "D"}, {point_name: "E"} ]},
      {name: "Category 4", points: [ {point_name: "F"}, {point_name: "G"}, {point_name: "C"}, {point_name: "G"} ]},
      {name: "Category 5", points: [ {point_name: "A"}, {point_name: "B"}, {point_name: "H"}, {point_name: "H"} ]}
    ];
    var hashTable = {};
    data.forEach(d=>{
     var points = d.points;
     points.forEach(k=>{
       if(hashTable[k.point_name]){
       hashTable[k.point_name] ={
          count: hashTable[k.point_name].count +1,
          cat: [...hashTable[k.point_name].cat, d.name],
          categoryCount: hashTable[k.point_name].cat.includes(d.name) ? hashTable[k.point_name].categoryCount : hashTable[k.point_name].categoryCount+1
      } 
      
       }else{
          hashTable[k.point_name]  = {count: 1,
          cat: [d.name],
          categoryCount:1
        }}
     })
    })
// console.log(hashTable);
var res = [];
Object.keys(hashTable).forEach(o=>{
 res.push({
   name: o,
   count: hashTable[o].count,
   categories: hashTable[o].categoryCount
 })
});

console.log(res)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文