如何从 JS 数组中删除精确数量的重复值? [已关闭]

问题描述 投票:0回答:1

这里,我有一个包含 5 个数字的数组,其中 3 个(或更多)是相同的:

[1,1,4,2,1]

我怎样才能从数组中获取另外两个数字(在示例中,

[4,2]
)?

以下是一些测试用例:

[1,1,4,2,1] => [4,2] or [2,4]
[5,5,1,5,5] => [1,5] or [5,1]
[3,4,3,4,3] => [4,4]
[6,6,6,6,6] => [6,6]

我自己也尝试过一些事情,我决定数一下数字。我确实取得了一些进展,但不知道下一步该去哪里。

function getUniques(arr) {
  const counts = {};
  arr.forEach(num => {counts[num] = (counts[num]||0) + 1});
  const uniques = [];
  Object.keys(counts).forEach(n => {
    if (counts[n] === 1)
      uniques.push(Number(n));
  });
  return uniques;
}
console.log(getUniques([1,4,2,1,1])) // [2,4]
console.log(getUniques([6,3,3,6,6])) // []
console.log(getUniques([5,3,5,5,5])) // [3]
console.log(getUniques([4,4,4,4,4])) // []

javascript arrays duplicates
1个回答
0
投票

你的标准令人困惑。

实现此目的的最接近的方法是首先构建频率图,将其反转,按键过滤,取消反转,并跟踪第二次遍历时发生的命中。

当您期望最终场景出现

[3, 3]
时,删除 3 个或更多是有点含糊的。

const main = () => {
  console.log(eliminate([1, 1, 4, 2, 1])); // [4, 2]
  console.log(eliminate([1, 5, 1, 1, 1])); // [5, 1]
  console.log(eliminate([3, 3, 3, 3, 3, 3])); // [3, 3, 3]
};

const eliminate = (arr) => {
  const valToFreq = FrequencyMap.fromIterable(arr);
  const freqToVal = FrequencyMap.invert(valToFreq);
  const filteredByFreq = FrequencyMap.filterByKey(freqToVal, (k) => k > 2);
  const remaining = FrequencyMap.unInvert(filteredByFreq);
  const counter = FrequencyMap.clearValues(remaining);
  const result = [];
  for (let v of arr) {
    //console.log(v, Object.fromEntries(counter));
    if (!counter.has(v)) {
      result.push(v);
    } else {
      counter.increment(v, 1);
      if (counter.get(v) > 2) {
        counter.delete(v);
      }
    }
  }
  return result;
};

class FrequencyMap extends Map {
  increment(key, amount = 1, defaultValue = 0) {
    this.set(key, (this.get(key) ?? defaultValue) + amount);
    return this.get(key);
  }
  static fromIterable(iterable, accessor) {
    const map = new FrequencyMap();
    for (let item of iterable) {
      map.increment(accessor ? accessor(item) : item);
    }
    return map;
  }
  static invert(freqMap) {
    return Array.from(freqMap)
      .reduce((invertedMap, [key, freq]) =>
          invertedMap.set(freq, [...(invertedMap.get(freq) ?? []), key]),
      new FrequencyMap());
  }
  static unInvert(invertedMap) {
    return Array.from(invertedMap)
      .reduce((originalMap, [frequency, keys]) => 
          keys.reduce((map, key) => map.set(key, frequency), originalMap),
      new FrequencyMap());
  }
  static filterByKey(map, predicate) {
    return new FrequencyMap(Array.from(map.entries())
        .filter(([key, value]) => predicate(key)));
  };
  static clearValues(map, defaultValue = 0) {
    return new FrequencyMap(Array.from(map.entries())
        .map(([key]) => [key, defaultValue]));
  }
}

main();
.as-console-wrapper { top: 0; max-height: 100% !important; }

© www.soinside.com 2019 - 2024. All rights reserved.