我有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。有想法吗?
答案 0 :(得分:19)
您的代码的实际作用是:如果列表中存在城市“华沙”,列表中存在职位“ Web开发人员”,那么请给我所有薪水超过2k的人。由于样本数据(tautology)的前两个条件均成立,因此您编写的代码从列表中返回了薪水超过2k的所有人,这就是您观察到的结果,并在此处结束。
在这一点上,我建议您考虑一下您拥有的数据结构是否适合根据这些条件过滤人员。但是,假设您需要坚持使用当前的数据表示形式。此外,您编写和Barmar复制的代码效率极低。 (明智的)人会执行以下操作来完成此任务:
8.
。8.
。8.
。8.
。8.
。4.
。您是否在上述算法中看到任何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 functions和arrow 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
,它表示复数,这没关系,但是对于其余列表,您使用了单数名词-workplace
和job
。我建议您保持命名一致性,因为它也可以大大提高代码的可读性。
答案 1 :(得分: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);