То, что на самом деле делает ваш код, таково: если в списке существует город «Варшава», а в списке существует позиция «веб-разработчик», тогда получите мне всех людей с зарплатой более 2 тысяч. Поскольку первые два условия верны для ваших выборочных данных ( тавтология ), код, который вы написали, возвращает всех людей из списка с зарплатой более 2 тыс., Что вы и наблюдали и получили здесь.
На этом этапе я бы предложил вам подумать, подходит ли имеющаяся у вас структура данных для фильтрации людей по этим критериям. Но скажем, вам нужно придерживаться текущего представления данных. Кроме того, код, который вы написали и скопировал Barmar, невероятно неэффективен. Вот что (разумный) человек сделает для выполнения такой задачи:
- Найдите «Варшава» в списке рабочих мест и выделите его маркером; перейти к
8.
, если не найден.
- Найдите «Веб-разработчик» в списке вакансий и выделите его маркером; перейти к
8.
, если не найден.
- Найти первого человека с зарплатой> 2000; перейти к
8.
, если не найден.
- Поиск имени человека в списке выделенных лиц города; перейти к
8.
, если не найден.
- Поиск имени человека в списке рабочих заданий; перейти к
8.
, если не найден.
- Да, я нашел запись, которая соответствует критериям, нажмите ее для вывода!
- Найти следующего человека с зарплатой> 2000; перейдите к
4.
, если найдено.
- Готово! * * 1030
Вы видели какой-либо цикл for в алгоритме выше? Ну, некоторые скажут, что петли спрятаны там. И это правда, но в настоящее время у нас есть функции высшего порядка (надеюсь, вы не возражаете против кода Python), которые делают то же самое - скрывают циклы в них. Примером такой функции является Array.Filter
. Он принимает аргумент обратного вызова (делегат, лямбда, предикат, функция стрелки, callitwhatyouwant ...), который выполняется ровно один раз для каждого элемента массива в порядке их появления в массиве. Обратный вызов решает, следует ли сохранить конкретный элемент в результирующем массиве. Результатом функции является новый массив, заполненный элементами, для которых функция обратного вызова вернула true
. Давайте начнем опираться на эту функцию.
const array = people.filter(person => person.salary > 2000);
Здесь я передал функцию стрелки в качестве параметра из-за ее краткого синтаксиса. Эта строка кода эффективно реализует шаги #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 &&
в третьей строке, но я предпочитаю держать его там, чтобы не вводить "загадку" в логику.
Так что мы узнали здесь? Почему мы должны были пройти через это? Если вы сравните исходный код, основанный на цикле, с приведенным выше, вы быстро обнаружите, что последний более читабелен, потому что он в основном написан на простом английском языке и более эффективен, потому что он избегает выполнения ненужных шагов. И в качестве бонуса, возможно, сегодня был день, когда вы узнали что-то о функциях высшего порядка и функциях стрелок .
Вот фрагмент.
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
. Я бы порекомендовал вам сохранить согласованность имен, поскольку это также значительно улучшает читабельность кода.