2013-10-03 107 views
0

我在JavaScript中有三個陣列,例如:洗牌多個相關的陣列

one = [1,2,3,4]; 
two = [5,6,7,8]; 
three = [9,10,11,12]; 

然後,如果我打電話給shuffle(one,two,three)那麼它可能會產生

one = [2,3,1,4]; 
two = [6,7,5,8]; 
three = [10,11,9,12]; 

如何看2,6,和10 stlil對齊,所有三個都有相同的索引,例如?這就是我在其他列表中保持相互關聯的數字的意思。

如何編寫上述定義的shuffle函數?

+0

什麼......不知道誰改變了它的排序。這裏沒有排序。 – CodeGuy

+0

最簡單和「最普遍」的方法是將每個索引映射到單個對象上,執行排序/隨機播放,然後映射回去。當然,如果您可以從:values = [{one :, two :, three:},{..}]開始,那麼整個過程可能會更簡單。 – user2246674

+0

@CodeGuy您可以將「shuffle」替換爲「sort」,最終結果是相同的(不包括排序功能)。我知道我看過之前的排序(排序也是一個原始標籤)。 – user2246674

回答

1
zip = function() { 
    var args = [].slice.call(arguments, 0); 
    return args[0].map(function(_, i) { 
     return args.map(function(a) { 
      return a[i] 
     }) 
    }) 
} 

unzip = function(a) { 
    return a[0].map(function(_, i) { 
     return a.reduce(function(y, e) { 
      return y.concat(e[i]) 
     }, []) 
    }) 
} 

shuffle = function(a) { 
    for (var i = a.length - 1; i > 0; i--) { 
     var j = Math.floor(Math.random() * (i + 1)); 
     var t = a[i]; 
     a[i] = a[j]; 
     a[j] = t; 
    } 
    return a; 
} 

z = unzip(shuffle(zip(one, two, three))) 
one = z[0] 
two = z[1] 
three = z[2] 

有點冗長,但工程...

另一種選擇,也許在這種情況下更快:

range = function(n) { 
    for(var r = [], i = 0; i < n; i++) 
     r.push(i); 
    return r; 
} 

pluck = function(a, idx) { 
    return idx.map(function(i) { 
     return a[i]; 
    }); 
} 

r = shuffle(range(one.length)) 
one = pluck(one, r) 
two = pluck(two, r) 
three = pluck(three, r) 

而且,這將是最好有一個數組的數組,而不是三個變量:

matrix = [ 
    [1,2,3,4], 
    [5,6,7,8], 
    [9,10,11,12] 
]; 

r = shuffle(range(matrix[0].length)); 
matrix = matrix.map(function(row) { 
    return pluck(row, r) 
}); 
+0

不應該在函數前面以及'z',''''''''''''''和'''''變量前面有'var'關鍵字嗎? –