Как отобразить объекты массива, используя простой цикл и операторы if? - PullRequest
9 голосов
/ 11 июня 2019

У меня есть 3 массива и пара простых циклов.Я хочу указать 3 условия, при которых человек из Варшавы будет работать на должности веб-разработчика с зарплатой более 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 ]

19 голосов
/ 11 июня 2019

То, что на самом деле делает ваш код, таково: если в списке существует город «Варшава», а в списке существует позиция «веб-разработчик», тогда получите мне всех людей с зарплатой более 2 тысяч. Поскольку первые два условия верны для ваших выборочных данных ( тавтология ), код, который вы написали, возвращает всех людей из списка с зарплатой более 2 тыс., Что вы и наблюдали и получили здесь.

На этом этапе я бы предложил вам подумать, подходит ли имеющаяся у вас структура данных для фильтрации людей по этим критериям. Но скажем, вам нужно придерживаться текущего представления данных. Кроме того, код, который вы написали и скопировал Barmar, невероятно неэффективен. Вот что (разумный) человек сделает для выполнения такой задачи:

  1. Найдите «Варшава» в списке рабочих мест и выделите его маркером; перейти к 8., если не найден.
  2. Найдите «Веб-разработчик» в списке вакансий и выделите его маркером; перейти к 8., если не найден.
  3. Найти первого человека с зарплатой> 2000; перейти к 8., если не найден.
  4. Поиск имени человека в списке выделенных лиц города; перейти к 8., если не найден.
  5. Поиск имени человека в списке рабочих заданий; перейти к 8., если не найден.
  6. Да, я нашел запись, которая соответствует критериям, нажмите ее для вывода!
  7. Найти следующего человека с зарплатой> 2000; перейдите к 4., если найдено.
  8. Готово! * * 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. Я бы порекомендовал вам сохранить согласованность имен, поскольку это также значительно улучшает читабельность кода.

14 голосов
/ 11 июня 2019

Вам нужно проверить, есть ли 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...