查找并返回数组中最常出现的元素

时间:2019-03-24 19:34:54

标签: arrays typescript for-loop return mode

我需要实现一个名为findMode的函数来查找数组的模式。假设数组仅包含整数。当调用函数并且数组为空时,它返回0。当调用函数并且数组不为空时,它应该返回在数组中最频繁出现的元素。如果数组包含多个模式,则应返回模式的最小值。我需要创建一个中间数组,另一个数字数组,以计算每个值出现的次数。该数组应使用数组的索引号来跟踪b中的数字被计数了多少次。

以下是我到目前为止的内容:

import { print } from "....";

export let main = async () => {
    let input = [2, 1, 1, 2, 1, 0]
    print(mode(input))

};

export let findMode = (b: number[]): number => {
    let newArr: number[] = []; /** this is the new number array created to store count, this is the intermediate array */
    if (b.length === 0) {
        return 0;
    for (let i = 0; i < b.length; i++) {


};
main();

以下是预期/实际结果:

如果数组是b [2,1,1,2,1,0],则应返回1,并且如果我们打印创建的数组以存储计数,则应打印newArr [1,3,2]因为元素0有1个出现,元素1有3个出现,元素2有2个出现。想法是从0作为输入数组中的元素,到0作为中间数组中的索引。所以最后我们看到哪个是我们的最大出现次数(或中间数组中的max元素)在索引1处是3,所以模式是1。

如果数组为b [0,0,0,1,1,2,1,1],则应返回1。如果数组为b [4,4,7,4,0,7],则应返回4。如果数组为b [-4,-4,-1,3,5],则应返回-4。如果数组为b [1,1,2,3,2],则应返回1,因为它是最小的模式。如果数组为b [10,10,10,20,20,30],则应返回10。

2 个答案:

答案 0 :(得分:0)

这样的作品行吗?

export let findMode = (b: number[]): number => {
    // we'll store the values in b and the number of times they occur here
    const counts: Array<{ value: number, count: number }> = [];

    // it helps to check that b is defined before you check length, this avoids ReferenceErrors
    if (!b || !b.length) {
        return 0;
    }

    for (let i = 0; i < b.length; i++) {
        const val = b[i];
        const count = counts.find(count => count.value === val);

        if (count) {
            count.count++;
        } else {
            counts.push({ value: val, count: 1 });
        }
    }

    // get the mode by sorting counts descending and grabbing the most occuring
    const mode = counts.sort((c1, c2) => c2.count - c1.count)[0];

    // and now if you *need* an intermediate array with the index mapped to the value and value mapped to the count:
    const largestNumber = counts.sort((c1, c2) => c2.value - c1.value)[0];
    // initialize an empty as long as the largest number
    let newArr = new Array(largestNumber);
    newArr = newArr.map((val, i) => {
        const count = counts.find(count => count.value === i);
        if (count) {
            return count.count;
        } else {
            return 0; // 'i' occurs 0 times in 'b'
        }
    });
};

答案 1 :(得分:0)

您可以使用Array#reduce方法来实现结果,并带有一个用于保持计数的附加对象。

export let findMode = (b: number[]): number => {
  // object for keeping count of each element
  // initially set `0` with 0 count (default value)
  let ref = {
    '0': 0
  };

  return b.reduce((value, num) => {
    // define count as 0 if not defined 
    ref[num] = ref[num] || 0;

    // increment element count
    ref[num]++;
    // if number count is gretater than previous element count
    // then return current element
    if (ref[num] > ref[value]) {
      return num;
    // if counts are same then return the smallest value
    } else if (ref[num] === ref[value]) {
      return num < value ? num : value;
    }
    // else return the previous value
    return value;
    // set initial value as 0(default)
  }, 0);
};

let findMode = b => {

  let ref = {
    '0': 0
  };

  return b.reduce((value, num) => {
    ref[num] = ref[num] || 0;
    ref[num]++;
    if (ref[num] > ref[value]) {
      return num;
    } else if (ref[num] === ref[value]) {
      return num < value ? num : value;
    }
    return value;
  }, 0);
};


[
  [2, 1, 1, 2, 1, 0],
  [1, 3, 2],
  [0, 0, 0, 1, 1, 2, 1, 1],
  [4, 4, 7, 4, 0, 7],
  [-4, -4, -1, 3, 5],
  [1, 1, 2, 3, 2],
  [10, 10, 10, 20, 20, 30]
].forEach(v => console.log(findMode(v)))