2017-02-24 8 views
1

私はこれを解決するための最善の最小限の操作を探しています。配列を値とランクとして含む並べ替え辞書

var sourceDictionary = { 
    "200" : [ 
     [ "a", 5 ], 
     [ "al", 6 ], 
     [ "xl", 8 ] 
    ], 
    "201" : [ 
     [ "b", 2 ], 
     [ "al", 16 ], 
     [ "al", 26 ], 
     [ "al", 9 ], 
     [ "al", 3 ] 
    ], 
    "202" : [ 
     [ "lm", 7 ] 
    ] 
} 

IはoutputputDictionaryに示すように、各キー内に含まれる整数値に基づいて辞書をソートし、各値をランク付けします。

var targetDictionary = { 
    "200" : [ 
     [ "a", 5, "rank-7" ], 
     [ "al", 6, "rank-6" ], 
     [ "xl", 8, "rank-4" ] 
    ], 
    "201" : [ 
     [ "b", 2, "rank-9" ], 
     [ "al", 16, , "rank-2" ], 
     [ "al", 26, "rank-1" ], 
     [ "al", 9, "rank-3" ], 
     [ "al", 3, "rank-8" ] 
    ], 
    "202" : [ 
     [ "lm", 7, "rank-5" ] 
    ] 
} 

例えば[ "al", 26, "rank-1" ] .Thisは、他のすべての値のうちの最大である26としてランク1です。

Javascriptが配列は参照渡しされているので、あなたはこのようにそれを利用することができます最善の最適解のための最も好ましいlanguage.Looking

+3

あなたはこの自分を解決しようと試みたことがありますか? – zfrisch

+1

私のアプローチは普通だった...辞書をループし、すべての配列を1つの変数に集めて(そして参照を保持する)、それらを並べ替え、ランクを割り当てて、それを元のターゲット構造に戻す...その多くもし私が辞書に50万の鍵があると思えば、私のアプローチは本当に吸います。より良いアプローチをしている人を探してください。 – gully

+0

おそらく間違いがあります。ランク-7はありません。それは意図的なのかそれとも間違いですか? –

答えて

3

です:

function rankify(obj) { 
 
    // PHASE 1: get a reference of all the sub-arrays 
 
    var references = []; 
 
    for(var key in obj) {    // for each key in the object obj 
 
    obj[key].forEach(function(e) { // for each element e (sub-array) of the array obj[key] 
 
     references.push(e);    // push a reference of that array into reference array 
 
    }); 
 
    } 
 
    
 
    // PHASE 2: sort the references 
 
    references.sort(function(a, b) { // sort the items 
 
    return b[1] - a[1];    // to reverse the sort order (a[1] - b[1]) 
 
    }); 
 
    
 
    // PHASE 3: assign the ranks 
 
    references.forEach(function(e, i) { // for each array in the reference array 
 
    e.push("rank-" + (i + 1));  // push another item ("rank-position") where the position is defined by the sort above 
 
    }); 
 
} 
 

 

 
var sourceDictionary = {"200" : [[ "a", 5 ],[ "al", 6 ],[ "xl", 8 ]],"201" : [[ "b", 2 ],[ "al", 16 ],[ "al", 26 ],[ "al", 9 ],[ "al", 3 ]],"202" : [[ "lm", 7 ]]}; 
 

 
rankify(sourceDictionary); 
 
console.log(sourceDictionary);

矢印機能を使用することが許可されている場合:

function rankify(obj) { 
 
    Object.keys(obj) 
 
     .reduce((ref, k) => ref.concat(obj[k]), []) // get the references array 
 
     .sort((a, b) => b[1] - a[1])     // sort it 
 
     .forEach((e, i) => e.push("rank-" + (i + 1))); // assign the rank 
 
} 
 

 

 
var sourceDictionary = {"200" : [[ "a", 5 ],[ "al", 6 ],[ "xl", 8 ]],"201" : [[ "b", 2 ],[ "al", 16 ],[ "al", 26 ],[ "al", 9 ],[ "al", 3 ]],"202" : [[ "lm", 7 ]]}; 
 

 
rankify(sourceDictionary); 
 
console.log(sourceDictionary);

+0

これを他のソリューションと比較して最善の解決策としてマークするのは... – gully

0

これは数行で行うことができます:あなたが最初に元のオブジェクトからkey|indexを格納する配列にそれを軽減し、それを並べ替えることができ

var sourceDictionary = { 
 
    "200" : [ 
 
     [ "a", 5 ], 
 
     [ "al", 6 ], 
 
     [ "xl", 8 ] 
 
    ], 
 
    "201" : [ 
 
     [ "b", 2 ], 
 
     [ "al", 16 ], 
 
     [ "al", 26 ], 
 
     [ "al", 9 ], 
 
     [ "al", 3 ] 
 
    ], 
 
    "202" : [ 
 
     [ "lm", 7 ] 
 
    ] 
 
} 
 

 
var flatten = arr => [].concat.apply([], arr) 
 
var ranks = flatten(Object.keys(sourceDictionary) 
 
    .map(k => sourceDictionary[k].map(t => t[1])) 
 
) 
 
    .sort((a, b) => b - a) 
 
    .filter(function(item, index, inputArray) { 
 
     // remove duplicates 
 
     return inputArray.indexOf(item) == index; 
 
    }); 
 

 
Object.keys(sourceDictionary) 
 
    .forEach(k => sourceDictionary[k] 
 
    .forEach(t => t.push("rank-" + (1 + ranks.indexOf(t[1]))))) 
 

 
console.log(sourceDictionary)

+2

ソートの代わりに、他の順序( 'b-a')でソートするだけです。 –

+0

ああ良い点:) – fafl

0

ランクプロパティを追加し、オブジェクトを再度作成します。

var data = { 
 
    "200" : [ [ "a", 5 ], [ "al", 6 ], [ "xl", 8 ] ], 
 
    "201" : [ [ "b", 2 ], [ "al", 16 ], [ "al", 26 ], [ "al", 9 ], [ "al", 3 ] ], 
 
    "202" : [ [ "lm", 7 ] ] 
 
} 
 

 
var o = Object.keys(data).reduce(function(r, e) { 
 
    data[e].forEach((a, i) => r.push([e + '|' + i, a])) 
 
    return r; 
 
}, []) 
 

 
o.sort((a, b) => b[1][1] - a[1][1]).map(function(e, i) { 
 
    e[1][2] = 'rank-' + (i + 1) 
 
}) 
 

 
var result = o.reduce(function(r, e) { 
 
    var key = e[0].split('|') 
 
    if (!r[key[0]]) r[key[0]] = [] 
 
    r[key[0]][key[1]] = e[1] 
 
    return r 
 
}, {}) 
 

 
console.log(result)

+0

キーとインデックスを別々に保存するのではなく、 '|'文字で結合するのはなぜですか? – Bergi

関連する問題