2017-08-03 153 views
2

我正在阅读CRLS并在JavaScript中实现算法。通过在javascript中排序来随机播放数组

在第5.3节 - 通过排序进行排列,在尝试提出简单算法的有效实现时,我感觉自己像一个莫朗。下面是伪代码: shuffle by sorting

这是我实现

Array.prototype.sortShuffle = function() { 
    const LENGTH = this.length; 
    const CUBE = Math.pow(LENGTH, 3); 

    let P = this 
     .map((e, i) => { 
      return {v: Math.floor(Math.random() * CUBE), e: e} 
     }) 
     .sort((e1, e2) => e1.v > e2.v); 

    P.forEach((e, i) => this[i] = e.e); 
} 

我使出了这个悲伤的解决方案,因为本地Array.prototype.sort不提供比较的指标,A。排序((e1,e2,i1,i2)=> ...)可能已经完成了。

谁能请提供更有效的解决方案(不执行上述所有排序功能)

回答

1

您可以将其他阵列保持尽可能这使得代码,这是一个有点清洁“元组”。

Array.prototype.sortShuffle = function() { 
    return this.map(v => [Math.random() * this.length ** 3, v]) 
      .sort(([k1,v1],[k2,v2]) => k1 - k2) 
      .map(([k, v]) => v); 
} 

在速度方面 - 你最好使用Fisher-Yates或其他O(n)算法。

请注意,您在实现中出现错误,因为sort期望比较函数返回正数或负数(而不仅仅是布尔值)。

2

你的代码实际上做得很不错,但可以只使用一些样式改进:

Array.prototype.sortShuffle = function() { 
    const nCubed = Math.pow(this.length, 3); 

    this.map(v => ({ k: Math.random() * nCubed, v })) 
     .sort(({ k: k1 }, { k: k2 }) => k1 - k2) 
     .forEach(({ v }, i) => this[i] = v); 
}; 

特别是,你可以使用shorthand property namesobject destructuring,以及消除一些不必要的变数。另外,你不需要使用Math.floor,因为浮点数也可以。