PrimuS PrimuS - 4 months ago 12
PHP Question

Search nested multidimensional array

I have a function that fills an array:

foreach ($request->get('ids') as $id) {
$pdfArray['other']++; // Yes this is initialized
$pdfArray['rows'][$i]['id'] = $schedule->getId();
$pdfArray['rows'][$i]['date'] = $schedule->getStart()->format('d.m.Y');
$pdfArray['rows'][$i]['dateSort'] = $schedule->getStart()->format('Y-m-d H:i');
$pdfArray['rows'][$i]['from'] = $schedule->getStart()->format('H:i');
$pdfArray['rows'][$i]['to'] = $schedule->getEnd()->format('H:i');
$pdfArray['rows'][$i]['desc'] = $schedule->getDescription();
}


What I want to do

On each loop, I want to check if the array (so far) already has a
desc
entry equal to the current
$schedule->getDescription()
AND the same
date
as
$schedule->getStart()->format('d.m.Y')
(actually more, but let's keep it simple)

What I tried

public function recursive_array_search($needle,$haystack) {
foreach($haystack as $key=>$value) {
$current_key=$key;
if($needle===$value OR (is_array($value) && $this->recursive_array_search($needle,$value) !== false)) {
return $current_key;
}
}
return false;
}


Source

I use it like that:

if ($this->recursive_array_search($schedule->getDescription(), $pdfArray['rows']) &&
$this->recursive_array_search($schedule->getStart()->format('d.m.Y'), $pdfArray['rows'])){
$pdfArray['ma'][$schedule->getId()]++;
}


but this is
true
when ANY of the
start
or
desc
are SOMEWHERE in the current array.

How would I check if
desc
is found and
start
is in the SAME
$i
level?

EDIT for example

Let's say I have 10
$id
s to loop through. After 2 loops, the
$pdfArray
looks like this:

Array
(
[other] => 2
[rows] => Array
(
[0] => Array
(
[id] => 1
[date] => 13.07.2016
[dateSort] => 2016-07-13 08:00
[from] => 08:00
[to] => 09:00
[desc] => TEST
)

[1] => Array
(
[id] => 2
[date] => 12.07.2016
[dateSort] => 2016-07-12 08:00
[from] => 08:00
[to] => 09:00
[desc] => TEST
)

)


)

The next iteration has the following:

$schedule->getStart()->format('d.m.Y')
=>
12.07.2016


$schedule->getDescription()
=>
TEST


So I want to have the info that the combination already exists in the array.

BUT

$schedule->getStart()->format('d.m.Y')
=>
12.07.2016


$schedule->getDescription()
=>
TEST2


should NOT return true upon checking of it exists.

Answer

To test for a "duplicate" you can use this function:

function testPresence($pdfArray, $desc, $date) {
    foreach ($pdfArray["rows"] as $row) {
        if ($row["desc"] == $desc && $row["date"] == $date) return true;
    }
}

Example use:

echo testPresence($pdfArray, "TEST2", "12.07.2016") ? "Found" : "Not found"; // Not found
echo testPresence($pdfArray, "TEST", "12.07.2016") ? "Found" : "Not found"; // Found

In your original loop, you can use it as follows:

foreach ($request->get('ids') as $id) {
    if (testPresence($pdfArray, $schedule->getDescription(), 
                                $schedule->getStart()->format('d.m.Y')) {
        // We have a duplicate. Maybe skip this entry?:
        continue;
    }

    $pdfArray['other']++;
    $pdfArray['rows'][$i]['id'] = $schedule->getId();
    $pdfArray['rows'][$i]['date'] = $schedule->getStart()->format('d.m.Y');
    $pdfArray['rows'][$i]['dateSort'] = $schedule->getStart()->format('Y-m-d H:i');
    $pdfArray['rows'][$i]['from'] = $schedule->getStart()->format('H:i');
    $pdfArray['rows'][$i]['to'] = $schedule->getEnd()->format('H:i');
    $pdfArray['rows'][$i]['desc'] = $schedule->getDescription();
}