按元素出现次数对数组进行排序

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

我正在寻找一种优雅的方法来根据数组元素的出现次数对数组进行排序。

例如,在:

['pear', 'apple', 'orange', 'apple', 'orange', 'apple']

输出应该是这样的

['apple', 'orange', 'pear']

我尝试循环遍历数组并将出现的事件保存在另一个临时数组中,但这个解决方案非常糟糕。

javascript arrays
7个回答
10
投票

需要两个循环。

    var arr = ['pear', 'apple', 'orange', 'apple', 'orange', 'apple'];
    //find the counts using reduce
    var cnts = arr.reduce( function (obj, val) {
        obj[val] = (obj[val] || 0) + 1;
        return obj;
    }, {} );
    //Use the keys of the object to get all the values of the array
    //and sort those keys by their counts
    var sorted = Object.keys(cnts).sort( function(a,b) {
        return cnts[b] - cnts[a];
    });
    console.log(sorted);


2
投票

将值映射到水果→计数关联对象:

var counted = fruits.reduce(function (acc, fruit) {
    if (acc[fruit]) {
        acc[fruit]++;
    } else {
        acc[fruit] = 1;
    }
    return acc;
}, {});

将该对象映射到可排序数组中:

var assoc = counted.keys().map(function (fruit) {
    return [fruit, counted[fruit]];
});

对数组进行排序:

assoc.sort(function (a, b) { return a[1] - b[1]; });

提取值:

var result = assoc.map(function (i) { return i[0]; });

0
投票

您可以减少数组以删除重复项,然后使用自定义比较器进行排序:

var sorted = ['pear', 'apple', 'orange', 'apple', 'orange', 'apple'].reduce(function(result, item) {
    result.every(function(i) {
        return i != item;
    }) && result.push(item);
    return result;
}, []).sort(function(i1, i2) {
    return i1 > i2;
});
console.log(sorted);

0
投票

使用 linq.js 非常简单(使用 example):

var array = ['pear', 'apple', 'orange', 'apple', 'orange', 'apple'];            
var res = Enumerable.From(array).GroupBy(function (x) { return x; }).Select(function (x) { return { key: x.Key(), count: x.Count() } }).OrderByDescending(function (x) { return x.count }).Select(function (x) { return x.key}).ToArray();

0
投票

你可以尝试一下lodash。您需要做的就是

group
sort
,然后
map
,就完成了。

var arr = ['pear', 'apple', 'orange', 'apple', 'orange', 'apple'];

document.body.innerHTML = _(arr).chain().groupBy()
  .sortBy(function(a) {
    return -a.length;   // <- Note: Remove the negation to sort in ascending order.
  }).map(function(a) {
    return a[0];
  }).value().join(', ');
<script src="https://cdn.rawgit.com/lodash/lodash/master/dist/lodash.js"></script>


0
投票

试试这个:

var arr = ['pear', 'apple', 'orange', 'apple', 'orange', 'apple'];
var result = [];
var count = 0;

arr.sort();

for (var i = 0; i < arr.length; i++) {
  count++;
  if (arr[i] != arr[i + 1]) {
    result.push({
      "count": count,
      "value": arr[i]
    });
    count = 0;
  }
}

result.sort(function(a, b) {
  if (a.count < b.count) return 1;
  if (a.count > b.count) return -1;
  return 0;
});

console.log(result.map(function(item){return item.value}));


0
投票

对于遗留的 JS 版本,我最终得到了这个。

    function sortByOccurrence(arr_in){
        var arr_out = [];
        var c = {}; // count obj

        for (var i = 0; i < arr_in.length; i++) {
            var p = arr_in[i];
            c[p] = (c[p] || 0) + 1;
        }

        for (var p in c) if ( c.hasOwnProperty(p) ) arr_out.push(p);
        arr_out.sort(function(a, b) { return c[b] - c[a];});
        return arr_out;
    }
© www.soinside.com 2019 - 2024. All rights reserved.