2013-05-23 8 views
5

結果:Javascriptを:ソート最初のアレイに基づく多次元配列をソート私はこれに似た配列を設定している

var ary1 = new Array("d", "a", "b", "c"); 
var ary2 = new Array("ee", "rr", "yy", "mm"); 

var mdAry = new Array(ary1, ary2); 

ARY1とARY2インデックスは、物事の壮大なスキームで相互に関連した情報です。

d ee 
a rr 
b yy 
c mm 

私は()ARY1をソートし、取得することができます:

a 
b 
c 
d 

を私は独立してARY2を並べ替えた場合、私はなるだろう:

アウト記載されているとき、視覚的にARY1とARY2の接続を切断
ee 
mm 
rr 
yy 

を。 ary1のソートされたソリューションを取得し、それをary2に適用できますか?私はこれを取得したい:いない場合、それはmdAry [0]残りなインデックスへの解決策をソート適用されるよう

a rr 
b yy 
c mm 
d ee 

は、ソートすることmdAryだろうか?

+0

それはおそらくにより理にかなって列ではなく行でデータを保持する。その後、簡単に行をソートすることができます。 – Halcyon

+0

残念ながら、私はリストボックスのGUIを設定しています。列1はa、b、c、dであり、列2はrr、yy、mm、eeの内容である。一度表示されると、各リストボックスの項目行は1つのアセットに関連する情報です。 –

+0

可能な重複エントリを処理する必要がありますか?[a、a、b、c]のように? – sixFingers

答えて

0

あなたは可能性がありそれらを2つのプロパティを持つ1つのオブジェクトに「マージ」し、最初のものをソートして最後に分離します(see demo here):

function sortBoth(ary1, ary2) { 
    var merged = []; 
    for (var i=0; i < ary1.length; i++) merged.push({'ary1': ary1[i], 'ary2': ary2[i]}); 
    merged.sort(function(o1, o2) { return ((o1.ary1 < o2.ary1) ? -1 : ((o1.ary1 == o2.ary1) ? 0 : 1)); }); 
    for (var i=0; i < merged.length; i++) { ary1[i] = merged[i].ary1; ary2[i] = merged[i].ary2; } 
} 

var ary1 = new Array("d", "a", "b", "c"); 
var ary2 = new Array("ee", "rr", "mm", "yy"); 

console.log(ary1); 
console.log(ary2); 

sortBoth(ary1, ary2); 

console.log(ary1); 
console.log(ary2); 

出力:これを行うには

[ "d", "a", "b", "c"] 
["ee", "rr", "mm", "yy"] 
[ "a", "b", "c", "d"] 
["rr", "mm", "yy", "ee"] 
+0

私の状況に最も適したソリューション。ありがとう、それは素晴らしい作品です。 –

+0

@DavidTorno素晴らしいですが、データストレージの戦略が最適ではないことに加えて、バンドエイドであると言ってもかまいません。 – ErikE

0

あなたの例では、結果が

a rr 
b mm 
c yy 
d ee 

(私が正しく理解している場合)でなければなりませんので、この1つはジョブにすべきである:

ここにデモの作業
Array.prototype.sortRelated = function(related) { 
    var clone = this.slice(0), 
     sortedRelated = []; 
    clone.sort(); 

    for(var i = 0; i < this.length; i ++) { 
     sortedRelated[clone.indexOf(this[i])] = related[i]; 
    } 

    return sortedRelated; 
} 

var ary1 = new Array("d", "a", "b", "c"); 
var ary2 = new Array("ee", "rr", "mm", "yy"); 

var sorted = ary1.sortRelated(ary2); 

http://jsfiddle.net/cwgN8/

1

一つの方法は、より簡単にソートすることができるものに、データ構造を変換し、その後

var ary1 = ["d", "a", "b", "c"], 
    ary2 = ["ee", "rr", "mm", "yy"] 
    mdAry = [ary1, ary2]; 

// convert to form [[d, ee], [a, rr], ..] 
var tmp = mdAry[0].map(function (e, i) { 
    return [e, mdAry[1][i]]; 
}); 
// sort this 
tmp.sort(function (a, b) {return a[0] > b[0];}); 
// revert to [[a, b, ..], [rr, mm, ..]] 
tmp.forEach(function (e, i) { 
    mdAry[0][i] = e[0]; 
    mdAry[1][i] = e[1]; 
}); 
// output 
mdAry; 
// [["a", "b", "c", "d"], ["rr", "mm", "yy", "ee"]] 
後に戻って変換することです
+0

これは最も直感的な解決策だと思います。また、UIコンポーネントに表示されているボトルネックがソートされていないと仮定すると、十分に効率的です。 –

+0

私が考えた別の方法は、ソートアルゴリズムの独自の実装を書いて、2番目の配列で同じ変換を行うようにしましたが、JavaScriptで乱雑になります。第3の考え方は最初のものと似ていますが、tmp [i] [1]の 'ary2'値の代わりに指標を使うと、他の配列のこれらのインデックスを変更するループがあります。すべての値のコピー。 –

+0

肯定 - ソートインデックスはオプションです。 (range(len(myList))、key = myList .__ getitem__) –

1

さらに別のメソッドを追加するだけで、最初の配列からソート「結果」を取得し、それをany他の関連リストに適用することができます。

function getSorter(model) { 
    var clone = model.slice(0).sort(); 
    var sortResult = model.map(function(item) { return clone.indexOf(item); }); 

    return function(anyOtherArray) { 
     result = []; 
     sortResult.forEach(function(idx, i) { 
      result[idx] = anyOtherArray[i]; 
     }); 
     return result; 
    } 
} 

その後、

var arr = ["d", "a", "b", "c"]; 
var arr2 = ["ee", "rr", "yy", "mm"]; 

var preparedSorter = getSorter(arr); 
preparedSorter(arr2); 
//=> ["rr", "yy", "mm", "ee"]; 

あるいは、

multidimensional = [arr, arr2]; 
multidimensional.map(getSorter(arr)); 
// => [["a", "b", "c", "d"], ["rr", "yy", "mm", "ee"]] 
+0

配列内の値が一致すると、これは間違って始まります。つまり、 'getSorter(['a'、 'b' 、 'a'、 'b']) 'は' [0、0、2、2] '形式の' sortResult'を生成するので、 'result'はインデックス' 1'を_undefined_、長さ '3' 。 –

+0

あなたは一意のメンバーでしか動作しないのは間違いありません。私はそれを修正することができます私は表示されます。 – matehat

3

あなたの配列項目が関連している場合は、それらを一緒に格納します。

var arr = [ 
    {x: 'd', y: 'ee'}, 
    {x: 'a', y: 'rr'}, 
    {x: 'b', y: 'yy'}, 
    {x: 'c', y: 'mm'} 
]; 

arr.sort(function(a, b) { 
    if (a.x != b.x) { 
     return a.x < b.x ? -1 : 1; 
    } 
    return 0; 
}); 
+1

"配列アイテムが関連している場合は、それらをまとめて格納します" ...データ構造誰ですか? +1 – Gabriel

+0

私はあなたのソート関数が文字列値で数学をしようとするので、私はあなたに+1を与えたいと思います...? – ErikE

+0

@ErikE 16進数を比較しないのですか? ;-) 更新しました! –

関連する問題