首页 > 解决方案 > Ramda:在另一个数组中查找一个数组的最低次数

问题描述

我有两个包含字符串的数组。第二个数组只能包含字符串,它们在第一个数组中,但可以包含多次。我试图找到第二个数组中出现次数最少的单词。这里有些例子:

const original = ['foo', 'bar', 'baz'];

const arr1 = ['foo', 'bar']; // => ['baz'] because 'baz' is 0 times in arr1.
const arr2 = ['foo', 'foo', 'bar']; // => ['baz'] because 'baz' is 0 times in arr2.
const arr3 = ['foo', 'foo', 'bar', 'bar', 'baz']; // => ['baz'] because 'baz' in 1 time in arr3.
const arr4 = ['foo', 'bar', 'baz']; // => ['foo', 'bar', 'baz']; because they are all the lowest (1 time).
const arr5 = ['foo', 'foo', 'bar', 'bar', 'bar', 'baz', 'baz']; // => ['foo', 'baz'] because they are both only 2 times in arr5

你会怎么用 Ramda 做这个?(或者一般在 JS 中)?我觉得它可以解决,R.countBy但我不知道如何获得所有具有最低值的键。

标签: arraysecmascript-6countingramda.js

解决方案


一个普通的 ES6 版本还不错:

const minOccurences = (orig, xs) => 
  Object .entries (xs .reduce (
    (a, x) => ({... a, [x]: (a [x] || 0) + 1}),
    Object .assign (... orig .map (x => ({[x]: 0})))
  )).reduce(
    ({vs, m}, [v, c]) => c < m ? {vs: [v], m: c} : c == m ? {vs: [...vs, v], m} : {vs, m},
    {vs: [], m: Infinity}
  ).vs

const original = ['foo', 'bar', 'baz'];

console.log (minOccurences(original, ['foo', 'bar'])); // => ['baz'] because 'baz' is 0 times in arr1.
console.log (minOccurences(original, ['foo', 'foo', 'bar'])); // => ['baz'] because 'baz' is 0 times in arr2.
console.log (minOccurences(original, ['foo', 'foo', 'bar', 'bar', 'baz'])); // => ['baz'] because 'baz' in 1 time in arr3.
console.log (minOccurences(original, ['foo', 'bar', 'baz'])); // => ['foo', 'bar', 'baz']; because they are all the lowest (1 time).
console.log (minOccurences(original, ['foo', 'foo', 'bar', 'bar', 'bar', 'baz', 'baz'])); // => ['foo', 'baz'] because they are both only 2 times in arr5
.as-console-wrapper {min-height: 100% !important; top: 0}

我们首先在调用{foo: 0, bar: 0, baz: 0}中从原始数组创建一个基本计数对象。Obect.assign我们将其作为初始值提供给第一个reduce调用,将第二个数组折叠成类似{foo: 2, bar: 3, baz: 2}. 然后我们的第二个reduce调用将其折叠成类似的东西{vs: ['foo', 'baz'], m: 2},其中m是最小计数和vs具有该计数的项目。然后我们vs从结果中提取出来,我们就有了答案。


推荐阅读