如何用JavaScript解决停车场的难题

271 阅读8分钟

你听说过停车场的挑战吗?如果没有,让我简单地解释一下。

停车场是一项挑战,要求你编写一个管理假想停车场的类。

在本教程中,我们将用JavaScript来完成这个任务。为了让它更有趣,我们将创建一个小的React应用程序,以可视化的方式展示我们的类的工作情况。

让我们开始吧。🎉

挑战要求

在这个挑战中,你必须用JavaScript实现一个类。这个类应该由变量和方法组成,模拟停车场的工作方式。以下是具体内容:

  • 我们应该能够创建具有特定大小(停车位数量)的停车场。
  • 我们不区分不同的车辆 - 我们认为它们都是一样的
  • 我们的类提供了一个将新车停放在停车场的方法
  • 我们的类提供了一个移除已停放车辆的方法,以及
  • 我们的类提供了一种方法来获得停车场的大小(停车位的总数)。

停车场的挑战解决方案

首先,让我们看一下类的逻辑本身。

它非常简单明了,所以对你们中的大多数人来说可能不会有任何惊喜--特别是如果你已经有一些OOP和基于类的语言的编程经验。

类ParkingLot

我将首先给你代码,然后我将对实现进行简短的解释:

class ParkingLot {
  slots = [];

  constructor(parkingSize) {
    this.slots = new Array(parkingSize).fill(null);
  }

  park(carId) {
    console.log(`Parking car: ${carId}`);
    if (this.slots.every((slot) => slot !== null)) {
      return false;
    }

    for (let i = 0; i <= this.slots.length; i++) {
      const slot = this.slots[i];

      if (slot === null) {
        this.slots[i] = carId;
        return true;
      }
    }
  }

  remove(carId) {
    console.log(`Leaving car: ${carId}`);
    if (this.slots.every((slot) => slot !== carId)) {
      return false;
    }

    for (let i = 0; i <= this.slots.length; i++) {
      const slot = this.slots[i];

      if (slot === carId) {
        this.slots[i] = null;
        return true;
      }
    }
  }

  getSlots() {
    console.log(`Parking slots: ${this.slots}`);
    return this.slots;
  }

  getSize() {
    console.log(`Parking size is: ${this.slots.length}`);
    return this.slots.length;
  }

  getAvailable() {
    const availableSlots = this.slots.filter((s) => s === null).length;
    console.log(`Available parking slots: ${availableSlots}`);
    return availableSlots;
  }

  isFull() {
    return this.getAvailable() === 0;
  }
}

export default ParkingLot;

从头开始--我们的类有一个属性,slots ,这将是一个数组,用于存储关于停车位的信息(无论它们是空闲还是被占用)。

然后,我们有一个constructor 方法,在你每次创建这个类的实例时都会执行。在这里,我们使用一个输入的数字参数,称为parkingSize ,来创建一个长度等于该数字的空数组。

从技术上讲,这个数组不是空的,因为我们用空值初始化它。这意味着,在构造函数中执行代码后,我们最终会得到一个充满空值的数组,这取决于我们传入的数字。

例如,如果我们执行这个:

const parking = new ParkingLot(5);

它的结果将是这样的:

[null, null, null, null, null] // lenght = 5

instead of [] // empty array, length 0

在经历了构造函数之后,让我们来看看这个类中的其他方法。

park() - 这就是我们实际停车的地方。这个方法在 数组上进行迭代,检查是否有空位(即仍等于null的槽),并在这些空位上添加汽车。slots

汽车是由carId 。这只是一个标识符,我们用它来表示我们有一辆车在某个位置。注意,如果没有空位,这个方法返回false,如果停车成功,则返回true。

getSlots() - 帮助方法,只是返回我们用来存储停车位的数组。

remove() - 这就是我们如何从停车场移除汽车的方法。这个方法也是对车位数组的迭代。

到目前为止,你可能已经注意到,在几乎所有的情况下,当我们需要操作存储在数组这样的数据结构中的数据时,我们必须对这个结构进行迭代,以便我们能够访问它的元素。

不同的编程语言提供了不同的数据结构和方法来处理它们,但主要的想法总是相同的:当你需要对这些数据做什么时,你需要以某种方式迭代它。

为了从停车场移走一辆车,我们使用上述的标识符。我们在slots数组中寻找这样的项目,如果我们得到一个匹配,我们就有一辆车可以 "取消停车"。我们通过再次将那个特定的槽设置为空来执行实际的移除。

现在你可以猜到为什么我们一开始就决定用null来初始化我们的slots数组。

这个方法也会返回一个布尔值的结果,取决于是否成功移除。

在建立某种能够对这种变化作出反应的用户界面时,我们应该能够使用这种反馈。在向停车场添加汽车时也是如此(请看park 方法)。

getSize() - 另一个帮助方法,我们用来检查停车场的大小。

getAvailable() - 这个告诉我们目前有多少个可用的车位。

isFull() - 告诉我们,如果停车场已经满了,就是没有可用的车位了。

如何构建React应用程序

image-92

停车场应用程序 - 主屏幕

这里是有趣的开始。🕺

我们将创建一个交互式应用程序,将我们可以在上述实现的帮助下执行的任务可视化。

我们的应用程序将提供基本的用户界面控制,允许一个(假想的)操作员与停车场软件一起工作*。* 为了使他们的工作更加赏心悦目,我们将尝试把我们的软件提供的基本功能做成动画。

让我们来看看如何!📺

源代码

这里是该应用程序的源代码的repo

让我给你一个关于什么为什么的简单总结。

该应用程序是用vite构建的。原因是我最近一直在使用它,我对它的速度和性能非常满意。

不管它仍然处于相对早期的开发阶段--如果我即将开始一个新的项目,并处于可以选择的位置,我将选择vite

这并不是说我对它的老大哥CRA有什么意见。相反,我已经用它建立了多个应用程序,而且我仍然在我的一些项目中使用它。只是vite要快得多,而且经常能提供我目前需要的一切。

💡请记住,选择一种特定的技术总是取决于你对特定项目的具体需求。这就是说,没有什么银弹。它始终是一个需求和优先级的问题。

React应用程序的结构

image-93

应用程序的结构

该应用程序的结构是直接的。在根层,我们有两个文件夹--assetssrc。第一个文件夹包含应用程序中使用的资产(在本例中,它只是一个汽车图片)。后者包含所有的源代码文件。

让我们仔细看看source文件夹中的内容。

这里我们有以下文件夹:

  • components- 包含应用程序中使用的所有React组件
  • lib- 包含停车场类,负责应用程序的主要逻辑
  • pages- 包含两个子目录,分别用于应用程序中的两个主要屏幕--Landing和Main,。
  • utils- 包含一个帮助方法,用于生成虚构的汽车牌照,我们以后在表示停车位繁忙时使用该方法。
  • 还有几个文件,其中大部分与应用程序的入口点有关,除了favicon文件 - 它们的作用对你来说应该很清楚。如果没有,请看一下你的浏览器的标签😉。

image-94

带图标的浏览器标签

应用程序页面

如前所述,应用程序中的主要页面(也称为屏幕)被称为LandingMain。这些都是React组件本身。它们作为你在欢迎页面中看到的一切的骨架--你最初登陆的地方,以及你可以选择你想在停车场中拥有多少个停车位的地方。

image-95

欢迎页面

点击大的、ping的提交按钮后进入的页面--你的操作员能够管理停车场的主屏幕。

image-96

主页面

应用程序的功能

该应用程序为管理一个假想的停车场提供了非常基本的功能。当用户选择他们想要的插槽数量(最多20个),他们将被过渡到主屏幕。在那里,用户将能够看到所有的免费停车位。

当一辆车被停放时,通过PARK!按钮,相关的位置将被可视化为繁忙状态,并将显示正在停放的汽车的注册号码。操作员可以通过点击繁忙的车位,也就是他们想从停车场 "移除 "的汽车,来解除汽车的停放。

💡移动的红色汽车的简单动画只是为了视觉效果,对停车场的工作方式没有任何实际影响。

我使用CSS模块来设计应用程序的风格。我还试图使这个应用程序对移动设备友好一些,以防你决定在你的移动设备上尝试。

做我的客人,试试吧 🧪

结论

我在这篇文章背后的最初想法是描述停车场类本身。你知道,只是为了教育目的。向你展示如何用JavaScript编写这样一个类。

但后来我觉得这有点无聊🥱。 我想创造一些更有趣的东西💃🏻,一些更游戏化的东西🕹️可以这么说。

这就是我为什么要做这个类似于迷你游戏的应用程序的原因。

在制作过程中,我5岁的女儿🧒🏻看到了它,并想和它玩。实际上她玩得很开心!

是的,是的,当然了!我并不是说,如果这对一个5岁的孩子来说是有趣的东西,那么对你来说也是如此😀。

我唯一的目标是通过游戏吸引你的注意力,让它背后的知识📖在你身上停留更久。

谢谢你的阅读!🙏