按元素出现频率对数组排序

时间:2019-08-27 14:42:09

标签: javascript arrays

我正在寻找一种有效的解决方案,以根据元素出现的次数对数组进行排序

例如:

let values = ["10", "4", "4", "4", "7", "7"]

我认为最好的输出类似于[{number, frequency}, ...],在示例中看起来像这样:

[{4, 3}, {7, 2}, {10, 1}]



我已经看到了很多方法,但是每种解决方案都只能根据频率对数组进行排序,而无法访问元素出现的次数。

此刻,我只有从另一个StackOverflow主题获得的代码(不记得哪个对不起)

var map = values.reduce(function(p, c) {
   p[c] = (p[c] || 0) + 1;
     return p;
 }, {});

var newTypesArray = Object.keys(map).sort(function(a, b) {
     return map[a] < map[b];
 });

console.log(newTypesArray);

在根据频率进行排序方面做得很好,但是我无法访问元素重复多少次。而且我不知道该怎么做... 有什么想法吗?

4 个答案:

答案 0 :(得分:0)

const arr = [1, 1, 1, 2, 2, 3];

// use reduce for that.

const result = arr.reduce((result, item) => {
  const count = result[item];
  
  if (count === undefined) {
    result[item] = 1;
  } else {
    result[item] += 1;
  }
  
  return result;
}, {});

// You'll get the result similar to this: {[item]: [count]}

// And then you can transform it into entries array:

const entries = Object.entries(result);

// entries are [[item, count], ...];

// And then sort
 
const sorted = entries.sort((entryA, entryB) => entryA[1] - entryB[1]);

// You'll have ascending sorted array by count.

console.log(sorted);

答案 1 :(得分:0)

类似这样的方法可能会解决问题:

const data = ["10", "7", "5", "4", "4", "7", "7", "4", "5", "4"];

const result = data.reduce((r, c) => (r[c] = (r[c] || 0) + 1, r), {});

var keys=Object.keys(result).sort((a,b)=>result[b]-result[a]); // sorted keys

console.log(keys.map(k=>k+':'+result[k])); // output, ordered by keys

由您决定如何返回结果。 result包含计数,keys包含实际值。

答案 2 :(得分:0)

  

我认为最好的输出应该是self.info = "<head><link rel=\"stylesheet\" type=\"text/css\" href=\"{dailyChest.css}\"></head>" self.info = "\(self.info)<center><div style=\"position: relative;background-image:url({toget.png}); background-size:contain;background-repeat:no-repeat;background-position: center center;width: 100%; height: 600px\"><lottie-player src=\"{animate.json}\" style=\"width: 100%; margin : 0 auto\" autoplay></lottie-player><div class=\"reward\"><img class=\"rotate\" src=\"{vshinereward.png}\" style=\"position: absolute;width : 200%;top: -50%;left : -50%\" /><div class=\"rewardBit\">50,000<span>pts</span></div></div></div></center>"; let regex = try! NSRegularExpression(pattern: "\\{(.*?)\\}", options: [.allowCommentsAndWhitespace]) regex.enumerateMatches(in:self.info.description, options: [], range: NSMakeRange(0, (self.info.description as NSString).length)) { (result, _, _) in var match = (self.info.description as NSString).substring(with: result!.range) match = match.replacingOccurrences(of: "{", with: "", options: .literal, range: nil) match = match.replacingOccurrences(of: "}", with: "", options: .literal, range: nil) if File_cache.isExists(filename: match) { print("filename \(match) exists") self.info.description = self.info.description.replacingOccurrences(of: "{\(match)}", with: File_cache.get(filename: match).path, options: .literal, range: nil) }else{ print("filename \(match) not exists") } }

实际上,它们在输出[{number, frequency}, ...]中不是有效的JavaScript objects,如果要成对显示,可以使用array中的array来代替,结果将是这样的:

arrays

在您的代码中,您几乎已经到了那里,但是您只需要映射第一次[[number, frequency], ...] 调用的结果即可获得所需的对:

reduce

答案 3 :(得分:0)

您现在可以对从Object.entries()获得的对象使用reduce,现在对键值对数组进行排序,最后映射到{number, frequency}的数组:

let values = ["10", "4", "4", "4", "7", "7"]


var map = Object.entries(values.reduce(function(p, c) {
                   p[c] = (p[c] || 0) + 1;
                     return p;
                 }, {}))
                .sort((a, b) => a[1] < b[1])
                .map((a) => ({[a[0]]:a[1]}));
console.log(map);