2

私は、Microsoft Excel のMODE.MULT関数の比較的複雑な実装を作成しました。この関数は、配列内で最も頻繁に発生する値または反復値の配列を返します。これは、ネストされた別のループを含む 3 つのループで実装されており、もっと簡単な方法があるのではないかと思います。詳細については、返された配列から重複する値を抽出するために、 Lo-Dashの_.uniqを使用しています。

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]

よろしくお願いします。

4

1 に答える 1

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;
}
于 2013-01-04T17:26:27.790 に答える