如何使用简单的循环和'if'语句显示数组对象?

VQS*_*VQS 9 javascript loops if-statement

我有三个数组和几个简单的循环。我想指定三个条件,以显示来自华沙的一个Web开发人员职位的薪水超过2000。问题是它显示的是两个记录,而不是一个。

我试过在每个循环中编写条件,但是我的组合都没有起作用。

var people = [
    {'name': 'Viola', 'salary': 2500, 'surname': 'Smith'},
    {'name': 'Boris', 'salary': 1300, 'surname': 'Popkovitch'},
    {'name': 'John',  'salary': 500,  'surname': 'Lynn'},
    {'name': 'Tom',   'salary': 3300, 'surname': 'Gates'},
    {'name': 'Levis', 'salary': 900,  'surname': 'Klark'},
];

var workplace = [
    {'city': 'New York',   'persons': ['Viola']},
    {'city': 'Manchester', 'persons': ['John', 'Boris']},
    {'city': 'Warsaw',     'persons': ['Tom', 'Levis']},
];

var job = [
    {'position': 'Head manager',  'workers': ['Boris']},
    {'position': 'Web developer', 'workers': ['Tom', 'Viola']},
    {'position': 'Principal',     'workers': ['Levis', 'John']}
];

var array = [];

for (var x = 0; x < people.length; x++) {
  for (var y = 0; y < workplace.length; y++) {
    for (var z = 0; z < job.length; z++) {
      if (workplace[y].city === 'Warsaw' && job[z].position === 'Web developer' && people[x].salary > 2000) {
        array.push(people[x]);
      }
    }
  }
};

console.log(array);
Run Code Online (Sandbox Code Playgroud)

我希望代码仅返回Tom对象,而不返回Tom和Viola。任何的想法?

Pet*_*olf 19

您的代码实际上是这样做的:如果列表中存在城市“华沙”,并且列表中存在职位“ Web开发人员”,那么请给我所有薪水超过2k的人。由于样本数据(重言式)中的前两个条件成立,因此您编写的代码从清单中返回所有人的薪水超过2k,这就是您观察到的结果,并在此处结束。

在这一点上,我建议您考虑一下您拥有的数据结构是否适合根据这些条件过滤人员。但是,假设您需要坚持使用当前的数据表示形式。此外,您编写和Barmar复制的代码效率极低。这是一个(明智的)将要完成的任务:

  1. 在工作场所列表中找到“华沙”,并用记号笔突出显示;8.如果找不到,请转到。
  2. 在工作列表中找到“ Web开发人员”,并用记号笔突出显示;8.如果找不到,请转到。
  3. 查找薪水> 2000的第一人;8.如果找不到,请转到。
  4. 在突出显示的城市人员列表中查找人员名称;8.如果找不到,请转到。
  5. 高亮显示的工作人员列表中的查找人姓名;8.如果找不到,请转到。
  6. 是的,我找到了一条符合条件的记录,将其推送到输出!
  7. 寻找下一个薪水> 2000的人;4.如果找到,请转到。
  8. 做完了!

您是否在上述算法中看到任何for循环?好吧,有人会说循环隐藏在那儿。的确是这样,但是如今,我们有功能完全相同的高阶函数(我希望您不要介意Python代码)-在其中隐藏循环。此类功能的一个示例是Array.Filter。它需要一个回调(委托,lambda,谓词,箭头函数,callitwhatyouwant等)参数,该参数对于数组中的每个元素仅执行一次,以使它们出现在数组中。回调决定特定元素是否应保留在结果数组中。该函数的结果是一个新数组,其中填充了回调函数为其返回的元素true。让我们开始构建此功能。

const array = people.filter(person => person.salary > 2000);
Run Code Online (Sandbox Code Playgroud)

由于语法简洁,我在这里传递了一个箭头函数作为参数。这行代码有效地实现了上述算法的step #3#7。这是步骤#1和的代码#2

const warsaw = workplace.find(aWorkplace => aWorkplace.city === 'Warsaw');
const webDeveloper = workplace && job.find(aJob => aJob.position === 'Web developer');
Run Code Online (Sandbox Code Playgroud)

我使用了Array.find函数来查找所需的记录。当然,这假定城市名称和位置名称在数组中是唯一的。您还记得关于数据结构的观点吗?但没关系,让我们将其放在一边。workplace &&第二行是为了防止无意义的查找,以防找不到“华沙”。现在放在一起:

const warsaw = workplace.find(aWorkplace => aWorkplace.city === 'Warsaw');
const webDeveloper = workplace && job.find(aJob => aJob.position === 'Web developer');
const array = (warsaw && webDeveloper && people.filter(person =>
  person.salary > 2000 &&
  warsaw.persons.includes(person.name) &&
  webDeveloper.workers.includes(person.name)
)) || [];
Run Code Online (Sandbox Code Playgroud)

我知道我可以warsaw &&在第三行省略,但我更喜欢保留在第三行,以免在逻辑中引入“难题”。

那么我们在这里学到了什么?为什么我们必须经历这个?如果将原始的for基于循环的代码与上面的代码进行比较,您会很快发现后者更具可读性,因为它基本上是用简单的英语编写的,并且效率更高,因为它避免了执行不必要的步骤。

作为奖励,也许今天是您了解高阶函数箭头函数的那一天。

这是代码段。

const array = people.filter(person => person.salary > 2000);
Run Code Online (Sandbox Code Playgroud)

我的最终观察结果是您使用了identifier people,它意味着复数,这没关系,但是对于其余列表,您使用了单数名词- workplacejob。我建议您保持命名一致性,因为它也可以大大提高代码的可读性。


Bar*_*mar 14

您需要测试是否people[x].name位于workplace[y].persons和中job[z].workers

var people = [
    {'name': 'Viola',   'salary': 2500, 'surname': 'Smith'},
    {'name': 'Boris',   'salary': 1300, 'surname': 'Popkovitch'},
    {'name': 'John',    'salary': 500, 	'surname': 'Lynn'},
    {'name': 'Tom', 	'salary': 3300, 'surname': 'Gates'},
    {'name': 'Levis', 	'salary': 900,  'surname': 'Klark'}, 
];

var workplace = [
    {'city': 'New York', 	'persons': ['Viola']},
    {'city': 'Manchester', 	'persons': ['John', 'Boris']},
    {'city': 'Warsaw', 		'persons': ['Tom', 'Levis']},
];

var job = [
    {'position': 'Head manager',    'workers': ['Boris']},
    {'position': 'Web developer',   'workers': ['Tom', 'Viola']},
    {'position': 'Principal',       'workers': ['Levis', 'John']}
];

var array = [];

for (var x = 0; x < people.length; x++) {
  for (var y = 0; y < workplace.length; y++) {
    for (var z = 0; z < job.length; z++) {
      if (workplace[y].city === 'Warsaw' && job[z].position === 'Web developer' && people[x].salary > 2000 
        && job[z].workers.includes(people[x].name) 
        && workplace[y].persons.includes(people[x].name)) {
        array.push(people[x]);
      }
    }
  }
};


console.log(array);
Run Code Online (Sandbox Code Playgroud)

  • 注意:正在[meta](https://meta.stackoverflow.com/questions/385942/how-can-we-prevent-so-veterans-from-posting-low-quality-answers?noredirect= 1#comment702574_385942)。 (7认同)