如何使用 Typescript/JS 查找数组中对象值的前 n 次出现?

How can I find the top n occurrences of an object value in an array using Typescript/JS?

使用 TypeScript 我有一个对象数组,它可能包含与数组中其他对象相同的值。例如,以下数组包含具有值 "intent" 的对象。我想找到前 3 个最常出现的意图:

[
  {
    "intent": "hello",
    "other_value": "blah"
  },
  {
    "intent": "hello",
    "other_value": "blahblah"
  },
  {
    "intent": "hi",
    "other_value": "anothervalue"
  },
  {
    "intent": "hello",
    "other_value": "what?"
  },
  {
    "intent": "hello",
    "other_value": "eh?"
  },
  {
    "intent": "hi",
    "other_value": "okthen"
  },
  {
    "intent": "yo",
    "other_value": "alright"
  },
  {
    "intent": "hi",
    "other_value": "yes"
  },
  {
    "intent": "yo",
    "other_value":"yawhat?"
  },
  {
    "intent": "hey",
    "other_value": "meh"
  }
]

我正在尝试获得某种可以轻松显示前 3 名的结果,可能是 key/value 对数组或其他东西:

[
  {
    "intent": "hello",
    "occurrences": 4
  },
  {
    "intent": "hi",
    "occurrences": 3
  },
  {
    "intent": "yo",
    "occurrences": 2
  }
]

以下是我尝试的解决方案:

function top3(array) {
    let results = [];
    array.forEach(item => {
        if (results[item.intent] != null) {
          results[item.intent] += 1
        } else {
          results[item.intent] = 1;
        }
    });

    results = results.sort();
    return results.slice(0, 3);
}

然而,这只是 returns 出现值的数组,而不是意图本身的名称。所以我很难用数组找到哪个值属于哪个意图。

我尝试遵循此解决方案中发布的答案:

Get the element with the highest occurrence in an array

但是,我无法弄清楚如何找到 n 次出现,而只是找到出现次数最多的一次。我不确定如何使用该逻辑继续查找接下来的几次事件。

使用Array#reduce创建这样的组:

const source = [{"intent":"hello","other_value":"blah"},{"intent":"hello","other_value":"blahblah"},{"intent":"hi","other_value":"anothervalue"},{"intent":"hello","other_value":"what?"},{"intent":"hello","other_value":"eh?"},{"intent":"hi","other_value":"okthen"},{"intent":"yo","other_value":"alright"},{"intent":"hi","other_value":"yes"},{"intent":"yo","other_value":"yawhat?"},{"intent":"hey","other_value":"meh"}];

const g = source.reduce((acc, item) => {
  if(!acc[item.intent]) {
    acc[item.intent] = 0;
  }
  
  acc[item.intent]++;
  return acc;
}, {});

let top3 = Object.entries(g).sort((a, b) => b[1] - a[1]).slice(0, 3);

console.log('groups', g);
console.log('top 3', top3);

您可以使用 Array#map 进一步将 top 3 集合转换为相应的对象,如下所示:

top3.map(item => { [item[0]]: item[1] });

您可以首先通过构建对象数组来获取具有计数的对象,按 occurences 降序排序,然后对数组进行切片以仅获取前三个元素。

var data = [{ intent: "hello", other_value: "blah" }, { intent: "hello", other_value: "blahblah" }, { intent: "hi", other_value: "anothervalue" }, { intent: "hello", other_value: "what?" }, { intent: "hello", other_value: "eh?" }, { intent: "hi", other_value: "okthen" }, { intent: "yo", other_value: "alright" }, { intent: "hi", other_value: "yes" }, { intent: "yo", other_value: "yawhat?" }, { intent: "hey", other_value: "meh" }],
    count = data
        .reduce((r, { intent }) => {
            r[intent] = r[intent] || { intent, occurences: 0 };
            r[intent].occurences++;
            return r;
        }, {}),
    top3 = Object
        .values(count)
        .sort((a, b) => b.occurences - a.occurences)
        .slice(0, 3);
    
console.log(top3);
console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }