2012-01-05 6 views
1

私は現在、JSとアンダースコアにかなり新しいです。私は特定の配列の中で最も特定の数字が出現するのを見たいと思う(今はvar aと言う)。熱心なパイソンユーザーとして、私は周波数テレグラフでそれを集計し、それをタプル[(1,3)、(2、2)、...]で出力し、そのように並べ替えることに慣れています。アンダースコアJavascript建物頻度グラフ

javascriptでこれを行うにはどうすればよいですか?

function votesTied() { 
    var a = [1, 2, 3, 1, 2, 4, 6, 1, 7]; 
    var tele = {}; 
    _.each(a, function(key) { 
    if (tele[key]) { 
     tele[key]++; 
    } else { 
     tele[key] = 1; 
    } 
    }); 

    var items = _.map(tele, function(frequency,key) { return [key,frequency]; }); 
    var results = _.sortBy(items, function(tuple) { return -1 * tuple[1]; }).value(); 

    return results.length > 1 && results[0][1] == results[1][1]; 
} 

私は文字通りこれをすべて1行のPythonで行うことができますので、私は尋ねます。私はアンダースコアまたはjavascriptでこれを書くためのよりエレガントな方法があると確信しています。

答えて

1

多分これは?

result = _.chain(a) 
    .groupBy(function(x) { return x }) 
    .map(function(v, k) { return [k, v.length] }) 
    .sortBy(function(x) { return -x[1] }) 
    .value(); 
5

それはそのようなもののために許可されていたので、アンダースコアmap()機能は、維持プロパティを持つオブジェクトを返すことができないことを残念だ:

var t = _.chain (a) 
      .groupBy (function (p) { return p; }) 
      .map (function (e) { return _.size (e); }) 
      .value(); 

だけに機能を書き換えるの短いですこれを許可して、私が思いつくことができる最高のものはこれです:

var t = {}; 
_.chain (a) 
    .groupBy (function (p) { return p; }) 
    .each (function (e, i) { 
    t[i] = _.size (e); 
    }); 

tのすべて。

UPDATE

私はそれが聞かせできなかったので、私はmap()さんアンダースコアのソースを確認し、上記の最初のスニペットを可能にするために、以下の変更を加えました:

_.map = function(obj, iterator, context) { 
    // determine the return type 
    if (_.isArray (obj)) { 
     var results = []; 
    } 
    else { 
     var results = {}; 
    } 
    if (obj == null) return results; 
    // @xxx: we need to override the native map(), thus the next line is commented out 
    // if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); 
    each(obj, function(value, index, list) { 
     results[index] = iterator.call(context, value, index, list); 
    }); 
    if (obj.length === +obj.length) results.length = obj.length; 
    return results; 
    }; 

私はそれを徹底的にチェックしていませんが、うまくいくはずです。

1

私はあなたが望む結果を達成するための第2の方法を考えましたが、それはコードの変更を必要としません。コードの明瞭さはわずかに低下するかもしれませんが、必要なステップは少なく、それはまだかなり明確です。下線のreduce()このような使用により

_.reduce([1, 2, 3, 1, 2, 4, 6, 1, 7], function(frequencies, value) { 
    frequencies[value] = frequencies[value] && frequencies[value] + 1 || 1; 
    return frequencies; 
}, {}); 

をドキュメントはreduce()の最初のパラメータが低下する配列である、と言うように、第二還元コールバックであり、第3は、初期状態でありますメモ/集約 - これは、削減中に頻度データを入力する空のオブジェクトです。

結果は次のようになります

{1: 3, 2: 2, 3: 1, 4: 1, 6: 1, 7: 1} 

それぞれの周波数にそれぞれ一意要素と値のキーを持つオブジェクトであること。

明瞭度が多少低下することがありますが、要求されたワンライナーに非常に近いため、在庫アンダースコア以上のものは必要ありません。