使用lambda使用lambda和正则表达式查找数组中最常见的数字

时间:2018-01-07 18:01:08

标签: javascript regex lambda

我知道这个问题已被问过几次,但是我没有找到理想的解决方案。

我的任务是找到数组中最常用的数字。首先我必须转换为数字,因为我们的输入是作为字符串给出的。之后,我使用lambda表达式对数组进行排序。 (我不明白它是如何工作的,我只知道它确实如此)。现在我想过滤数组[1,1,1,2,2,3,3,4,4,4,4,4,9,13]所以只有[4,4,4,4,4]离开了。我想使用.filter.reduce

function z(input) 
{
let numbers = input.map(n => +n)
                   .sort((a, b) => a - b)
                   .filter();

console.log(numbers);
}
z(['13', '4', '1', '1', '4', '2', '3', '4', '4', '1', '2', '4', '9', '3']);

如果有人可以解释:

function mode(arr){
    return arr.sort((a,b) => 
          arr.filter(v => v===a).length 
        - arr.filter(v => v===b).length
    ).pop();
}

mode(['pear', 'apple', 'orange', 'apple']); // apple

arr.sort上的回调有两个参数a和b但是之后我无法理解发生了什么。

事实上,任何关于如何使用lambda的指南都将受到赞赏。

3 个答案:

答案 0 :(得分:1)

您可以使用Map来收集具有相同值的元素,并通过检查数组的长度并根据以前的存储结果检查实际长度来采用单循环方法。

如果多个值具有相同的长度,则此方法可以考虑,然后以最大长度返回所有数组。



const z = a => {
        var m = new Map;
        return a.reduce((r, v, i) => {                            // create map
            var array = m.get(v) || m.set(v, []).get(v);          // get/create array
            array.push(v);                                        // push value
            if (!i || r[0].length < array.length) {               // take first or check
                return [array];                                   // return array
            }
            if (r[0] !== array && r[0].length === array.length) { // prevent push same a
                r.push(array);                                    // push with same len
            }
            return r;
        }, undefined);
    };

console.log(z(['13', '4', '1', '1', '4', '2', '3', '4', '4', '1', '2', '4', '9', '3']));
console.log(z(['pear', 'apple', 'orange', 'apple']));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 1 :(得分:1)

首先,如果您遍历数组直到结束,我认为您不需要对数组进行排序吗?

function z(input) {
    let map = new Map;
    let numbers = input.map(i => parseInt(i))
                   //.sort((a, b) => a - b)
                   .forEach(e => {
                        map.set(e, (map.get(e) || 0) + 1);
                   });

    return Array.from(map).reduce((a, b) => a[1] > b[1] ? a : b)[0];
}

说明:

  1. 创建一个地图,您可以使用该地图设置数字在数组中出现的次数。
  2. 使用parseInt将数组的每个元素转换为数字
  3. 对于数组中的每个项目(现在有数字而不是字符串),您需要从Map中获取出现次数(使用get函数),然后使用带有递增值的set函数将其设置回Map。 。 (map.get(e)|| 0)用于这是您第一次遇到此号码时。
  4. 最后,您可以使用Array.from提取地图的内容,这将为您提供锯齿状数组(如[[1,2],[3,4],[4,5]])。 每个内部数组将保存一对(数字,出现次数)。 您需要获取对中第二项中具有最高值的对,这意味着在锯齿状数组示例中为5,并提取该对中的第一项。您可以使用数组的reduce函数来完成。 reduce函数在数组中获取两个项,并期望返回一个具有与输入此函数的项相同形状的值,如下所示 reduce(a: A, b: A) => A表示接受A类型的两个参数并返回类型A的实例的函数。在您的示例中,它是: reduce(a: [Int, Int], b: [Int, Int]) => [Int, Int]表示获取两个类型为array的参数并返回一个数组。
  5. 因此reduce函数检查第一个数组在第二个索引中的数字是否大于第二个索引中的第二个数组。如果是,则返回第一个数组,而不是第二个索引中的值,否则返回第二个数组。 因为reduce函数输出必须与其每个参数的类型相同,否则返回值的类型也是一个数组,其第一个索引中包含数字,第二个索引中出现数字,因此您需要从中获取值第一个指数。

答案 2 :(得分:0)

您可以在这样的数组中找到最常见的元素:

function z(arr) {
  return Object.entries(arr.reduce((res, v) => {
    if(v in res) res[v]++;
    else res[v] = 1;
    return res;
  }, {})).sort((a, b) => a[1] < b[1])[0][0];
}

let a = z(['13', '4', '1', '1', '4', '2', '3', '4', '4', '1', '2', '4', '9', '3']);

console.log(a);

说明:

  1. arr.reduce的调用用于计算arr中每个元素的出现次数。
  2. 然后,我们使用arr.reduce将对象从[[key, value]]转换为像Object.entries这样的2D数组。
  3. 然后,我们根据每个子数组的第二个元素按降序对Object.entries数组进行排序。 (此元素是值部分)
  4. 然后我们选择排序数组中的第一个元素,并返回该元素[0][0]的关键部分。