2013-10-03 72 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'关键字吗? –