如何在javascript中计算数组中的重复值

IT技术 javascript arrays
2021-01-12 18:17:05

目前,我得到了一个这样的数组:

var uniqueCount = Array();

几步后,我的数组看起来像这样:

uniqueCount = [a,b,c,d,d,e,a,b,c,f,g,h,h,h,e,a];

如何计算数组中有多少 a、b、c?我想要这样的结果:

a = 3
b = 1
c = 2
d = 2

等等。

6个回答

const counts = {};
const sampleArray = ['a', 'a', 'b', 'c'];
sampleArray.forEach(function (x) { counts[x] = (counts[x] || 0) + 1; });
console.log(counts)

@SheetJS 如果您想知道为什么投反对票 - 是我;我在移动设备上浏览,并点击了按钮而实际上并没有注意到。一旦我发现它已经太晚了恢复。对此深表歉意,答案非常好。如果你想编辑它,我很乐意反转。
2021-03-13 18:17:05
这绝对是最简单的答案
2021-03-15 18:17:05
(counts[x] || 0)+1 这是如何给出计数的?
2021-03-19 18:17:05
@SidBhalke:如果设置,则表达式counts[x] || 0返回值counts[x],否则返回0然后只需添加一个并在对象中再次设置它,计数就完成了。
2021-03-20 18:17:05
还有reducevar counts = your_array.reduce((map, val) => {map[val] = (map[val] || 0)+1; return map}, {} );
2021-03-29 18:17:05

像这样的东西:

uniqueCount = ["a","b","c","d","d","e","a","b","c","f","g","h","h","h","e","a"];
var count = {};
uniqueCount.forEach(function(i) { count[i] = (count[i]||0) + 1;});
console.log(count);

如果您不想在旧浏览器中中断,请使用简单的 for 循环而不是 forEach。

多走一步并按总数排序的好方法是什么?
2021-03-15 18:17:05
@neelmeg 也许为“forEach”编写所有参数有助于更好地理解(“i”是每个数组值,而不是索引): uniqueCount.forEach(function(value, index) { count[value] = (count[value] || 0) + 1; });
2021-03-20 18:17:05
@web_dev 他创建了一个名为 count 的关联数组对象,该对象将为数组中的每个唯一元素都有一个键值对,其中键是唯一元素值,值是计数。他遍历数组,并为每个值增加值或创建键值对(不存在的键的值计算为未定义,因此 || 或运算符取零并添加 1)
2021-03-22 18:17:05

我偶然发现了这个(非常古老的)问题。有趣的是,最明显和优雅的解决方案(恕我直言)不见了:Array.prototype.reduce(...)自大约 2011 年(IE)或更早(所有其他浏览器)以来,所有主要浏览器都支持此功能:

var arr = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
var map = arr.reduce(function(prev, cur) {
  prev[cur] = (prev[cur] || 0) + 1;
  return prev;
}, {});

// map is an associative array mapping the elements to their frequency:
console.log(map);
// prints {"a": 3, "b": 2, "c": 2, "d": 2, "e": 2, "f": 1, "g": 1, "h": 3}

编辑:

通过在箭头函数中使用逗号运算符,我们可以用一行代码编写它:

var arr = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
var map = arr.reduce((cnt, cur) => (cnt[cur] = cnt[cur] + 1 || 1, cnt), {});

// map is an associative array mapping the elements to their frequency:
console.log(map);
// prints {"a": 3, "b": 2, "c": 2, "d": 2, "e": 2, "f": 1, "g": 1, "h": 3}

但是,由于这可能更难阅读/理解,因此您可能应该坚持使用第一个版本。

如果没有错误的参数重新分配,是否有不同的方法来做到这一点? prev[cur] = (prev[cur] || 0) + 1;
2021-03-15 18:17:05
@keyboard-warrior 你所说的“错误”是什么意思?这是完全合法的 JS 代码。它只是递增prev[cur],从0. (如果prev[0]未定义,0则使用该值)。您也可以改用该表达式(prev[cur] + 1) || 1,但这并没有太大区别。
2021-03-21 18:17:05

function count() {
    array_elements = ["a", "b", "c", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e", "a"];

    array_elements.sort();

    var current = null;
    var cnt = 0;
    for (var i = 0; i < array_elements.length; i++) {
        if (array_elements[i] != current) {
            if (cnt > 0) {
                document.write(current + ' comes --> ' + cnt + ' times<br>');
            }
            current = array_elements[i];
            cnt = 1;
        } else {
            cnt++;
        }
    }
    if (cnt > 0) {
        document.write(current + ' comes --> ' + cnt + ' times');
    }

}

count();

演示小提琴

您也可以使用高阶函数来进行运算。 看到这个答案

嗨@Vinay,也许你可以在这里帮助我?stackoverflow.com/questions/57819850/...
2021-03-17 18:17:05
循环后的额外 if 语句是不必要的......只需使用for (var i = 0; i <= array_elements.length; i++) {or<=代替<
2021-03-18 18:17:05

简单更好,一个变量,一个函数:)

const arr = ["a", "b", "c", "d", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e", "a"];

const counts = arr.reduce((acc, value) => ({
   ...acc,
   [value]: (acc[value] || 0) + 1
}), {});

console.log(counts);

我知道这很旧,但看起来很简单。任何人都可以向刚刚学习基本 reduce 用法的新手解释这里发生的事情。
2021-03-30 18:17:05
当然,reduce 允许您提供默认(第二个参数)值并将其通过 reduce 函数传回,以便您可以继续检查新值,acc(累积)将在我们循环遍历每个数组值时不断更新,在分配给它之后对于对象,我们可以检查它是否存在,并在我们迭代时将它的值更新为 1!希望这可以帮助 :)
2021-03-31 18:17:05