返回

当代码准确性不如简洁优雅时,以JS洗牌算法为例重新思考写代码的意义

见解分享

我们都很清楚,写代码应该首先保证的是它的正确性。如果连正确的代码都写不出来,那么写的代码再简洁优雅也是徒劳的。然而在代码设计、开发和交付的过程中,我们有时会面临一些两难的抉择,比如在代码的正确性和简洁优雅之间进行权衡。

在追求代码简洁优雅的同时,我们很容易忽视代码的正确性,导致最终交付的代码存在各种各样的错误。这些错误可能会导致应用程序出现故障,甚至可能造成安全问题。因此,在写代码的时候,我们首先要考虑的是代码的正确性,然后才是代码的简洁优雅。

为了更好地理解代码正确性和简洁优雅之间的关系,我们不妨来看一个具体的例子。假设我们要编写一个JS洗牌算法,将一个数组中的元素打乱顺序。

function shuffle(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

这是一个非常简洁优雅的洗牌算法,它只需要几行代码就可以实现。然而,这个算法存在一个问题,那就是它并不是完全正确的。

举个例子,假设我们要洗牌的数组是[1, 2, 3, 4, 5]。那么,使用这个算法洗牌后的结果可能是[2, 1, 3, 5, 4]。然而,我们期望的洗牌结果应该是[1, 3, 5, 2, 4]。

这是因为,这个算法没有考虑到洗牌过程中的随机性。在上面的例子中,算法在第一次迭代时,将数组中的1和2交换了位置。在第二次迭代时,算法又将数组中的2和1交换了位置。这样一来,数组中的1和2就又恢复到了原来的位置。

为了解决这个问题,我们需要对算法进行修改,使其能够考虑到洗牌过程中的随机性。

function shuffle(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    while (i === j) {
      j = Math.floor(Math.random() * (i + 1));
    }
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

通过对算法进行修改,我们确保了算法能够考虑到洗牌过程中的随机性,从而保证了算法的正确性。

当然,修改后的算法比原来的算法要复杂一些,但它却保证了算法的正确性。因此,在写代码的时候,我们应该首先考虑代码的正确性,然后再考虑代码的简洁优雅。