超市队列 - Javascript 最佳实践解决方案

The Supermarket Queue - Javascript Best Practice Solution

在我学习基础的旅行中javascript,我遇到了代码战争网站,它面临着不同的问题。我是 JavaScript 开发的新手,Code Wars 通过研究这些问题的最佳实践解决方案并尝试重构和理解它们,对理解基本的 js 逻辑有很大帮助。在 google、youtube 等的帮助下,我已经设法理解了大多数最佳实践解决方案,它帮助我加深了对 javascript 的理解,尽管我现在遇到了一个问题 - 并且一个最佳实践解决方案——但我就是无法理解它的逻辑和它是如何工作的。如果有人能用文字为傻瓜解释最佳实践解决方案,我将非常感激。

问题:超市自助收银台排队。您的任务是编写一个函数来计算所有客户结账所需的总时间! 所有说明都可以在 CodeWars 页面上找到:https://www.codewars.com/kata/57b06f90e298a7b53d000a86/train/javascript

最佳实践解决方案如下所示:

function queueTime(customers, n) {
  var w = new Array(n).fill(0);
  for (let t of customers) {
    let idx = w.indexOf(Math.min(...w));
    w[idx] += t;
    
  }
  return Math.max(...w);
}

样本测试:

Test.describe("example tests", function() {
Test.assertEquals(queueTime([], 1), 0);
Test.assertEquals(queueTime([1,2,3,4], 1), 10);
Test.assertEquals(queueTime([2,2,3,3,4,4], 2), 9);
Test.assertEquals(queueTime([1,2,3,4,5], 100), 5);

//add some more example tests here, if you like

})

我遇到的主要问题是我不明白 'w' 变量如何与 'for of' 函数交互。在我的理解中,'w' 是一个用零填充的数组,那么 w.indexOf 方法如何找到最小值。添加到 idx 变量的值?总的来说,我会非常感谢任何能够分解最佳实践解决方案的人。

谢谢, 杰罗姆

最初w是一个用0填充的数组

代码然后将 idx 设置为最低值的索引。

索引第一次为 0

let idx = [0,0,0,0,0].indexOf(Math.min([0,0,0,0,0])); // 0

所以 w[0] += t 变成 [1,0,0,0,0] 因为 t === 1

下次:

let idx = [1,0,0,0,0].indexOf(Math.min([1,0,0,0,0])); // 1

所以 w[1] += t 变成 [1,2,0,0,0] 因为 t === 2

等等

为了提高可读性,这里有相同的解决方案 re-written,并附有解释每个步骤的注释。

function queueTime(customers, n) {
  // creates an array of length n representing the tills
  // Each till is given a value of 0 to represent initial waitTime before the queue begins.
  const tills = new Array(n).fill(0);
  // goes through the queue of customer waitTimes
  for (let waitTime of customers) {
    // finds the till with the least wait time on it, adds the next customer's time to it
    const lowestWaitTill = tills.indexOf(Math.min(...tills));
    tills[lowestWaitTill] += waitTime;
  }
  // end result is that the waitTimes (load) on the tills are distributed optimally. 
  // The waitTime of the till with the heaviest load represents the total time taken
  return Math.max(...tills);
}

解决您关于“w”和“for of”循环的问题:

在此代码中,“w”重命名为 tills。 tills 数组中的每个索引代表一个结账收银台。 idx 重命名为“lowestWaitTime”,表示负载最少的收银台索引。

在for..of循环中,负载最小的till(索引)(最初为0,因为它们最初都是0)在这一行 const lowestWaitTill = tills.indexOf(Math.min(...tills));

Math.min(...tills)); 使用扩展运算符语法遍历收银台数组,并 returns 它找到的最低值,在本例中是任何收银台的最短等待时间。 tills.indexOf() returns first 包含传递给它的值的索引,在这种情况下将是负载最少的收银台的索引(分配的客户等待时间到它)。

所以,现在我们知道哪个收银台的负载最少,我们将当前客户的等待时间加到那个收银台上。然后我们移动到下一个客户并重复,直到没有客户离开。