これにはアンダースコアを使用したいのですが、何らかのばかげた理由でそれは私を逃れます:
数字のリストがあります: 39、39、10、1、3、4、5... など
最も頻度の高い 3 つと頻度の低い 3 つを返したいと思います。
_.countBy を使用してみましたが、どうにかしてオブジェクトを返すため、おそらく明らかなものを見逃していない限り、並べ替えが困難 (?) になります。
これにはアンダースコアを使用したいのですが、何らかのばかげた理由でそれは私を逃れます:
数字のリストがあります: 39、39、10、1、3、4、5... など
最も頻度の高い 3 つと頻度の低い 3 つを返したいと思います。
_.countBy を使用してみましたが、どうにかしてオブジェクトを返すため、おそらく明らかなものを見逃していない限り、並べ替えが困難 (?) になります。
私をクレイジーと呼んでください、しかしこれはアンダースコアのない解決策O(n log n)
です.最大3つを検索する代わりにソートするため、特に高速ではありませんO(n)
が、それが本当に重要な場合は修正できます.
配列を次のようにします。
var arr = [1,1,1,1,1,1,2,3,4,5,6,7,7,8,9,10,9,8,9,8]
まず、数値を頻度に減らします。
var t =arr.reduce(function(a,b){
a[b] = (b in a) ? a[b]+1 : 1; // set to 1 if not there, else increase
return a; // return the object
},{});
var res = Object.keys(t).sort(function(x,y){ // sort by frequency
return t[x] > t[y];
});
// Res more generally contains the frequencies ordered
alert(res[0]+" "+res[1]+" "+res[2]);
わかりましたので、私は嘘をつきました - 私はネイティブ JavaScript の吸盤です。これが「より簡単な」アンダースコア バージョンです。
obj = _.countBy(arr,function(num){return num; }); // get array by frequencies
var res = _.keys(obj).sort(function(x,y){ return obj[x] - obj[y]});
//res is now the same as above, to be honest I like the native version better :)
最初に、これはパラメーターなしでそれらをグループ化し (それぞれが同じ値を持つ新しい配列を作成するだけです)、次にそれらを結果の配列の長さで並べ替えます。次に、最初の 3 つの要素と最後の 3 つの要素を使用して、最小値と最大値の 2 つの新しい配列を作成します。 .map
によって作成された配列ではなく、最初の要素のみを返すために使用され.groupBy
ます。
EDIT : これは、Benjamin Gruenbaum による私の元の回答のより洗練された編集です。
var arr = [1,1,1,1,1,1,2,3,4,5,6,7,7,8,9,10,9,8,9,8];
var group = _.sortBy(_.groupBy(arr), "length");
var min = _.pluck(group.slice(0, 3),0);
var max = _.pluck(group.slice(-3),0);
console.log(min);
console.log(max);