Алгоритм вывода людей и мест работы

133
11 декабря 2018, 11:10

Есть список людей и список их мест работы. Например так:

$persons = [
    ['id' => 1, 'name' => 'user1'],
    ['id' => 2, 'name' => 'user2']
];
$jobs = [
    ['person_id' => 1, 'name' => 'job1'],
    ['person_id' => 1, 'name' => 'job2'],
    ['person_id' => 2, 'name' => 'job2']
];

У каждого человека может быть несколько мест работы (связь через person_id). Моя задача вывести их в таком формате:

person1(1, 2), person2(2)
job1(1), job2(2)

Т.е. около каждого имени человека стоят порядковые номера его мест работы. Заметьте - места работы могут повторяться, но вывестись должны без дублей. К сожалению мне не удалось придумать ни одного варианта как так можно вывести... Надеюсь на помощь или хотя-бы примерный алгоритм действий!

Answer 1

Немного переименуем исходные массивы:

$pdata = [['id' => 1, 'name' => 'user1'], ['id' => 2, 'name' =>'user2']];
$pjdata = [['person_id' => 1, 'name' => 'job1'], ['person_id' => 1, 'name' => 'job2'], ['person_id' => 2, 'name' => 'job2']];

Составим уникальный список работ с их номерами

$jobs = array_flip(array_unique(array_column($pjdata, 'name')));

Сделаем заготовку для массива $perons вида [1 => ['name' => 'user1', 'jobs' => [] ], ....]

$persons = array_map(function($p){ 
                 return ['name' => $p, 'jobs' => []];
              }, array_column($pdata, 'name', 'id'));

Теперь заполним поля jobs, пройдясь по массиву:

foreach($pjdata as $d){
    $persons[$d['person_id']]['jobs'][ $jobs[$d['name']] ] = $d['name'];
}

и собственно осталось вывести результат в нужном виде:

Array (
    [1] => Array  (
            [name] => user1
            [jobs] => Array (
                    [0] => 'job1'
                    [1] => 'job2'
                )    
        )    
    [2] => Array (
            [name] => user2
            [jobs] => Array (
                    [1] => 'job2'
                )    
        )    
)

Вывод, наверное, труда не составит, номера работ можно склеить через implode(',', array_keys($p['jobs']))

Answer 2

Итерируемся по массиву $persons на каждой итерации проходимся по массиву $jobs и находим все места работы персоны. Данные сохраняем в отдельный массив.

$persons = [['id' => 1, 'name' => 'user1'], ['id' => 2, 'name' => 'user2']];
$jobs = [['person_id' => 1, 'name' => 'job1'], ['person_id' => 1, 'name' => 'job2'], ['person_id' => 2, 'name' => 'job2']];
$p_j = [];
foreach ($persons as $person) {
  foreach ($jobs as $job)  {
    if ($job['person_id'] == $person['id']) {
        if (array_key_exists($person['id'], $p_j)) {
            if (!in_array($job['name'], $p_j[$person['id']])) {
                $p_j[$person['id']][] = $job['name'];
            }
        } else {
            $p_j[$person['id']][] = $job['name'];
        }
    }
  }
}
foreach ($persons as $person) {
  echo $person['name'] . '(';
  if (array_key_exists($person['id'], $p_j)) {
    echo implode(',', $p_j[$person['id']]);
  }
echo ') ';
}
echo "\n";
// user1(job1,job2) user2(job2) 

Надеюсь для вывода второго рядка сами правки сделаете

Answer 3

Если отталкиваться от того, что вся информация забирается из БД.

$personToJobs = [];
$jobToPersons = [];
$stmt = $db->query('SELECT DISTINCT person_id, name FROM persons_job_table');
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)){
    if(!isset($personToJobs[$row['person_id']])) $personToJobs[$row['person_id']] = [];
    if(!isset($jobToPersons[$row['name']])) $jobToPersons[$row['name']] = [];
    $personToJobs[$row['person_id']][] = $row['name'];
    $jobToPersons [$row['name']][] = $row['person_id'];
}

Вывод

foreach($personToJobs as $person => $jobs){
    echo "person".$person."(".implode(',', $jobs).")".PHP_EOL;
}
foreach($jobToPersons as $job => $persons){
    echo $job."(".implode(',', $persons).")".PHP_EOL;
}
READ ALSO
Как получить размер gif-картинки в ВК?

Как получить размер gif-картинки в ВК?

Знаю что в интернете есть полно функций, которые позволяют сделать это, но в ВК есть нюанс, например для скачивания гифки нельзя использовать...

131
Фильтрация данных по выбору select

Фильтрация данных по выбору select

Привет всем, объясните мне дураку как реализовать фильтрацию данных самим пользователем

131
0100 в 100 числовые значения

0100 в 100 числовые значения

Подскажите пожалуйста, в функцию попадает число, с ним внутри происходят математические операции, есть ли способ из числа 0100 получить 100 не прибегая...

153