如何重构检查数组长度的长if-else语句? [英] How can I refactor a long if-else statement checking array length?

查看:60
本文介绍了如何重构检查数组长度的长if-else语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个使用复选框过滤项目列表的程序.

I am writing a program that uses checkboxes to filter a list of items.

我有一组3个复选框: phase specialty type .选中复选框后,它们将被放入一个数组中,如果条件匹配,该数组将用于过滤出一个列表.

I have a group of 3 checkboxes: phase, specialty, and type. Once the checkboxes are marked, they are put into an array which is then used to filter out a list if the conditions match.

进行此操作时,我遇到了一些问题:

When making this, I ran into a few issues:

  • 如果未选中任何框,则根本不会显示任何列表.
  • 如果选中了所有类别中的一个框,则它将显示两个条件,而不是同时都为真(因此,如果我已选中阶段 Base 1 和专业 Race ,则列表将显示所有 Race 匹配项和所有 Base 1 匹配项)
  • 如果未选中一个框,但又选中了另一个框,则不会显示任何内容,因为这两个框都不适用.
  • If no boxes were checked, then no list would appear at all.
  • If a box in all categories were checked, then it would show both conditions rather than when both are true (so if I had phase Base 1 and specialty Race checked, then the list would show all Race matches and all Base 1 matches)
  • If a box was not checked but another one was, then nothing would appear since it didn't fit both categories.

要解决所有这三个问题,我做了一个 if,if/else 语句来检查每个类别的数组长度.如果所有数组(复选框)均为空(未选中),则将显示原始列表.如果选中了1个框,但未选中其他框,则没有任何损坏.等等.这是一个很长的声明.

To fix all three of these issues, I made an if, if/else statement to check the array length of each category. If all arrays (checkboxes) were empty (unchecked), then the original list would appear. If 1 box was checked, but the others weren't, then nothing would break. Etc.. This was made into quite a long statement.

现在,我确实打算增加2-3个复选框选项,并且不想让事情变得更加复杂.如果我继续按照现在的方式进行操作,那么最终可能会使当前的语句增加一倍.

Now, I do plan to add 2-3 more checkbox options, and don't want to complicate things even more. If I keep doing the way that I'm doing now, I may end up with double the current statements I have now.

当前,此列表的过滤方式如下,请注意,console.logs可以识别我正在使用的条件:

Currently, the way this list is being filtered is the following, note, the console.logs are to recognize which condition I am using:

if (phases.length === 0 && specialties.length === 0 && type.length === 0) {
      const workouts = this.workouts;
      this.selectedWorkouts.next(workouts);
    } else if (phases.length > 0 && specialties.length > 0 && type.length > 0) {
      const workouts = this.workouts.filter(
        workout => byPhase(workout) && bySpecialty(workout) && byType(workout)
      );
      this.selectedWorkouts.next(workouts);
      console.log("1 EVERYTHING CHECKED");
    } else if (
      phases.length > 0 &&
      specialties.length > 0 &&
      type.length === 0
    ) {
      const workouts = this.workouts.filter(
        workout => byPhase(workout) && bySpecialty(workout)
      );
      this.selectedWorkouts.next(workouts);
      console.log("2 PHASE AND SPECIALTY (no type)");
    } else if (
      phases.length > 0 &&
      specialties.length === 0 &&
      type.length > 0
    ) {
      const workouts = this.workouts.filter(
        workout => byPhase(workout) && byType(workout)
      );
      this.selectedWorkouts.next(workouts);
      console.log("3 PHASE AND TYPE (no specialty)");
    } else if (
      phases.length > 0 &&
      specialties.length === 0 &&
      type.length === 0
    ) {
      const workouts = this.workouts.filter(workout => byPhase(workout));
      this.selectedWorkouts.next(workouts);
      console.log("4 PHASE ONLY (no type or specialty)");
    } else if (
      phases.length === 0 &&
      specialties.length > 0 &&
      type.length > 0
    ) {
      const workouts = this.workouts.filter(
        workout => bySpecialty(workout) && byType(workout)
      );
      this.selectedWorkouts.next(workouts);
      console.log("5 SPECIALTY AND TYPE (no phase)");
    } else if (
      phases.length === 0 &&
      specialties.length > 0 &&
      type.length === 0
    ) {
      const workouts = this.workouts.filter(workout => bySpecialty(workout));
      this.selectedWorkouts.next(workouts);
      console.log("6 SPECIALTY ONLY (no phase nor type)");
    } else if (
      phases.length === 0 &&
      specialties.length === 0 &&
      type.length > 0
    ) {
      const workouts = this.workouts.filter(workout => byType(workout));
      this.selectedWorkouts.next(workouts);
      console.log("7 TYPE ONLY (no phase nor specialty)");
    }

是否有一种方法可以重构它,这样我就不会继续添加到语句中,从而使其成为更长的代码块?还是让我的发言时间这么长,这真的不是一个大问题吗?

Is there a way to refactor this so I don't continue to add on to the statements, making it an even longer block of code? Or is this not really much of a concern to keep my statement so long?

此处是我整个项目的重点.您可以在 src/app/features/workouts-page/workoutservice/workout.service.ts if/else 语句中找到 if/else 语句.代码>.上面找到的代码对于该语句应该足够具体.

Here is the stackblitz to my full project. You can find the if/else statements in src/app/features/workouts-page/workoutservice/workout.service.ts. The code is found above should be specific enough for this statement.

谢谢.

推荐答案

这就是我的方法.这使用一次 filter 通过:

Here's how I would do it. This uses a single filter pass:

filterWorkouts(phases: string[], specialties: string[], types: string[]) {
  const workouts = this.workouts.filter(workout => {
    return (
      (phases.length === 0 || phases.indexOf(workout.phase) >= 0) &&
      (specialties.length === 0 || specialties.indexOf(workout.specialty) >= 0) &&
      (types.length === 0 || types.indexOf(workout.type) >= 0)
    );
  });
  this.selectedWorkouts.next(workouts);
}

您需要为每个其他过滤器添加一个衬套.这是一个在stackblitz上有效的实现,供您试用.

You would need to add a one-liner for each additional filter is all. Here's a working implementation on stackblitz for you to play around with.

这篇关于如何重构检查数组长度的长if-else语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆