Есть список людей и список их мест работы. Например так:
$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)
Т.е. около каждого имени человека стоят порядковые номера его мест работы. Заметьте - места работы могут повторяться, но вывестись должны без дублей. К сожалению мне не удалось придумать ни одного варианта как так можно вывести... Надеюсь на помощь или хотя-бы примерный алгоритм действий!
Немного переименуем исходные массивы:
$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']))
Итерируемся по массиву $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)
Надеюсь для вывода второго рядка сами правки сделаете
Если отталкиваться от того, что вся информация забирается из БД.
$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;
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Знаю что в интернете есть полно функций, которые позволяют сделать это, но в ВК есть нюанс, например для скачивания гифки нельзя использовать...
Привет всем, объясните мне дураку как реализовать фильтрацию данных самим пользователем
Подскажите пожалуйста, в функцию попадает число, с ним внутри происходят математические операции, есть ли способ из числа 0100 получить 100 не прибегая...