如何改进MODE.MULT的这种实现

时间:2013-01-04 17:12:59

标签: javascript excel underscore.js excel-formula lodash

我编写了一个相对复杂的Microsoft Excel MODE.MULT函数实现,该函数返回数组中最常出现或重复值的数组。它实现了三个循环,包括一个嵌套到另一个循环,我怀疑有一个更简单的方法来实现它。有关信息,它使用_.uniq中的Lo-Dash从返回的数组中提取重复值。

function MODEMULT(range) {
  var n = range.length;
  var max = 0;
  var counts = new Array();
  var result = new Array();
  for (var i = 0; i < n; i++) {
    counts[i] = 0;
    for (var j = 0; j < n; j++) {
      if (range[j] === range [i]) {
        counts[i]++;
        max = (counts[i] > max) ? counts[i] : max;
      }
    }
  }
  for (var k = 0; k < n; k++) {
    if (counts[k] === max) {
      result.push(range[k]);
    }
  }
  return _.uniq(result);
}

出于测试目的,MODEMULT([1,2,3,4,3,2,1,2,3])应返回[2,3]

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

虽然会对内存使用产生影响,但您可以使用较少的循环,因为您将保留原始范围内所有唯一条目的计数:

function MODEMULT(range) {
  var n = range.length,
      // object to hold the number of occurrences per entry
      count= {},
      // array to hold those numbers which have the current max occurrences 
      maxItems = [],
      // reference to the current maximum
      max = 0,
      // JSLint placement of currentItem used inside the loop
      currentItem;

  for (var i = 0; i < n; i++) {
    currentItem= range[i];

    // Update the occurrences table.
    count[currentItem] = count[currentItem] ? count[currentItem] + 1 : 1;

    // If a new maximum is created, void the original maxItems and update max.
    if (count[currentItem] > max) {
       max = count[currentItem];
       maxItems = [];
    }

    // If the entry reaches the current max, add it to maxItems.
    if (count[currentItem] === max) {
        maxItems[maxItems.length] = currentItem;
    }
  }

  // No need for unique, as a duplicate value
  // will increase max and thus empty out maxItems.
  return maxItems;
}