计算对象数组中值的出现次数

时间:2017-05-17 18:51:34

标签: javascript node.js

我是Javascript的新手并在网上找到了一些练习。既然我想真正了解事情是如何运作的以及为什么某些方法比其他方法更好,我会很感激一些反馈,为什么我的方法不好(或好)。

我有一个XML并使用SAX解析器处理它以获得"趋势关键字"。总的来说,我的函数应该返回5个最受欢迎的函数。解析本身的结果是一个包含20个格式

的对象的数组
[{
  attributes: {}
  //children is just one big entry, separated by ';'
  children: ["Comey, James B;Federal Bureau of Investigation;Trump, Donald J;United States Politics and Government"]
  IsSelfClosing: false,
  name: 'ADX_KEYWORDS',
  parent: null,
  __proto__: {}
}]

现在我的想法是,提取所有children值并将其存储在新数组中

let flattenArr = keywords.reduce( (acc, cur) => acc.concat(cur.children), []);

结果我得到格式为

的数组(也是长度为20)
[["Comey, James B;Federal Bureau of Investigation;Trump, Donald J;United States Politics and Government"],
["Trump, Donald J;Comey, James B;Federal Bureau of Investigation;United States Politics and Government"]]

要处理单个值,我拆分数组

let mapArr = flattenArr
  .map( arr => arr.split(';') )
  .reduce( (acc, cur) => acc.concat(cur), [] );

因此,长度为115的新数组包含每个单独的关键字。这就是我不知道如何继续的地方。我尝试了MDN(Array.Reduce)的例子,但我真的不知道是否(以及如何)我能够处理这些对象。

//Result from MDN example, {value: quantity}
{ 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

所以我想为每个关键字创建一个对象,其数量属性为

{
  key: keyword,
  count: n
}

并尝试用

完成此操作
let countKeywords =  mapArrreduce( (allKeywords, keyword) => {
  if (allKeywords[0] != null && keyword in allKeywords[keyword]) {
    allKeywords[keyword].count++
  } else {
    allKeywords.push({
      keyword: keyword,
      count: 1
    })
  }
  return allKeywords;
}, []);   

但是我的代码不起作用,即使两天后我仍然很难让它工作,这让我发布了这个问题(这对我来说有点新,因为我总是在stackoverflow上找到我的答案,因此从来没有问过自己的问题)

2 个答案:

答案 0 :(得分:-1)

let countKeywords =  mapArr.reduce( (allKeywords, keyword) => {//typo <==
 var elem=allKeywords.find(el=>el.keyword===keyword);//its an array so allKeywords[keyword] wont work...
  if (elem) {
      elem.count++
  } else {
    allKeywords.push({
      keyword: keyword,
      count: 1
   })
 }
 return allKeywords;
}, []); 

答案 1 :(得分:-1)

应该可以这样做。由于您使用了大量嵌套数组,因此最终必须对平面贴图(reduce + concat)进行两次处理。您可以通过将其转换为原型方法来简化其可读性。

let flattenArr = [
    ["Comey, James B;Federal Bureau of Investigation;Trump, Donald J;United States Politics and Government"],
    ["Trump, Donald J;Comey, James B;Federal Bureau of Investigation;United States Politics and Government"],
    ["Trump, Donald J;Comey, James B;Federal Bureau of Investigation;United States Politics and Government"],
    ["Trump, Donald J;Comey, James B;Federal Bureau of Investigation;United States Politics and Government"]
]

let mapArr = flattenArr.reduce((a, b) => a.concat(b)).map(words => words.split(";")).reduce((a, b) => a.concat(b))

let orderedCount = mapArr.reduce(function (acc, cur) {
  if (typeof acc[cur] === 'undefined') {
    acc[cur] = 1;
  } else {
    acc[cur] += 1;
  }

  return acc;
}, {})

console.log(orderedCount)

输出:

{ 'Comey, James B': 4,
  'Federal Bureau of Investigation': 4,
  'Trump, Donald J': 4,
  'United States Politics and Government': 4 }

这里将flatMap作为原型ext:

Array.prototype.flatMap = function(lambda) { 
    return Array.prototype.concat.apply([], this.map(lambda)); 
}

然后使用它:

let mapArr = flattenArr.flatMap(a => a).map(words => words.split(";")).flatMap(a => a)