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

时间:2019-06-10 21:01:55

标签: javascript loops if-statement

我有3个数组和几个简单的循环。我想指定3个条件,该条件将显示来自华沙的一名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);

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

2 个答案:

答案 0 :(得分:19)

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

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

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

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

const array = people.filter(person => person.salary > 2000);

由于语法简洁,我在此处传递了arrow function作为参数。这行代码有效地实现了上述算法的步骤#3#7。这是步骤#1#2的代码:

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

我使用了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)
)) || [];

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

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

这是代码段。

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']}
];

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)
)) || [];

console.log(array);

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

答案 1 :(得分:14)

您需要测试people[x].nameworkplace[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);