ES6将数组元素的出现计数为对象数组中的值的最佳方法

时间:2018-08-22 10:37:24

标签: javascript ecmascript-6

我有一组这样的数据:

https://img.abc.com/xyz/valueOfURL

我想输出一个像这样的数组

[
  {
    name:'Bart',
    classes:['Maths','Philosophy','Music']
  },
  {
    name:'Lisa',
    classes: ['Maths','Literature','Music']
  },
  {
    name:'Maggie',
    classes: ['Quantum Physics','Literature']
  }
]

在ES6中实现它的最佳方法是什么?预先感谢!

编辑:我的尝试

[ 
  { "name": "Maths", "count": 2 },
  { "name": "Music", "count": 2 },
  { "name": "Literature", "count": 2 },
  { "name": "Quantum Physics", "count": 1 },
  { "name": "Philosophy", "count": 1 }
]

5 个答案:

答案 0 :(得分:3)

您可以将Array.reduce()forEach()内的reduce()循环一起使用来遍历classes数组:

var arr = [{
    name: 'Bart',
    classes: ['Maths', 'Philosophy', 'Music']
  },
  {
    name: 'Lisa',
    classes: ['Maths', 'Literature', 'Music']
  },
  {
    name: 'Maggie',
    classes: ['Quantum Physics', 'Literature']
  }
];

var res = arr.reduce((acc, obj) => {
  var classes = obj.classes;
  classes.forEach((subject) => {
      var exist = acc.find(({name}) => subject === name);
      if (exist) {
        exist.count++;
      } else {
        acc.push({
          name: subject,
          count: 1
        });
      }
  });
  return acc;
}, []);
console.log(res);

答案 1 :(得分:2)

我首先使用enter image description here创建了一个看起来如下的临时对象:

{
  "Maths": 2,
  "Philosophy": 1,
  "Music": 2,
  "Literature": 2,
  "Quantum Physics": 1
}

然后我遍历了临时对象以生成所需的输出

var originalData = [
  {
    name:'Bart',
    classes:['Maths','Philosophy','Music']
  },
  {
    name:'Lisa',
    classes: ['Maths','Literature','Music']
  },
  {
    name:'Maggie',
    classes: ['Quantum Physics','Literature']
  }
]

var tempCount = originalData.reduce((acc, elem) => {
  elem.classes.forEach((eachClass) => {
    if (eachClass in acc) {
      acc[eachClass] ++;
    }
    else {
      acc[eachClass] = 1;
    }
  })
  return acc
}, {});

console.log(tempCount)

var desiredResult = [];
for (var eachSub in tempCount) {
  if (tempCount.hasOwnProperty(eachSub)) {
    desiredResult.push({name: eachSub, count: tempCount[eachSub] })
  }
}

console.log(desiredResult)

答案 2 :(得分:1)

尝试此代码:

    var names=[],
    counts=[],
    output=[],
    input=[
      {
        name:'Bart',
        classes:['Maths','Philosophy','Music']
      },
      {
        name:'Lisa',
        classes: ['Maths','Literature','Music']
      },
      {
        name:'Maggie',
        classes: ['Quantum Physics','Literature']
      }
    ]
    for(i in input){
        for(j in input[i].classes){
            if (!names.includes(input[i].classes[j])){
                names.push(input[i].classes[j])
                counts.push(0)
            }
            counts[names.indexOf(input[i].classes[j])]++
        }
    }
    for(k in names){
        output.push({name:names[k],count:counts[k]})
    }
    console.log(output)

答案 3 :(得分:1)

您可以使用reduce&concat

let x = [{
    name: 'Bart',
    classes: ['Maths', 'Philosophy', 'Music']
  },
  {
    name: 'Lisa',
    classes: ['Maths', 'Literature', 'Music']
  },
  {
    name: 'Maggie',
    classes: ['Quantum Physics', 'Literature']
  }
]

let m = x.reduce(function(acc, curr) {
 // this will return an array of 'Maths', 'Philosophy', 'Music'...] 
 // & it will have duplicate elements
  return acc.concat(curr.classes)
}, []).reduce(function(acc, curr) {
  // again using reduce function to return an object key as subject name & count
  if (!acc.hasOwnProperty(curr)) {
    acc[curr] = 1
  } else {
    acc[curr] += 1
  }
  return acc;
}, {});
console.log(m)

答案 4 :(得分:0)

您可以:

let data = [
  {
    name:'Bart',
    classes:['Maths','Philosophy','Music']
  },
  {
    name:'Lisa',
    classes: ['Maths','Literature','Music']
  },
  {
    name:'Maggie',
    classes: ['Quantum Physics','Literature']
  }
]

let result = {}

for (let i of data) i.classes.forEach(j => {if (!result[j]) result[j]=0; result[j]++})

console.log(result)

它可能不是最佳选择,但看起来还不错


相同但更易理解

for (let student of data) {
  student.classes.forEach(clas => {
    if (!result[clas]) {
      result[clas]=0
    }
    result[clas]++
  })
}

// using "clas" because "class" is a reserved javascript word