1

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 $ids 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.

5
  • so you want to prevent your foreach if desk is somewhere in your array and start is in the same $i level? Commented Jul 15, 2016 at 8:12
  • Can you provide a small sample input and expected output please. I think I understand your question, but an example would be very helpful. Commented Jul 15, 2016 at 8:17
  • Edited with example Commented Jul 15, 2016 at 8:34
  • What is the final output you need? The array with "duplicates" removed? Or do you just need a function that tests a particular date & desc? Commented Jul 15, 2016 at 8:58
  • Only a test function. I will count up another var if that is the case... Commented Jul 15, 2016 at 9:00

3 Answers 3

1

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();
}
Sign up to request clarification or add additional context in comments.

1 Comment

Easiest to understand although the others seem to work too! Thank you!
1

try this at your validation function

    public function array_search($needle1, $needle2 ,$haystack) {
       foreach($haystack as $singleArray){  
          if (in_array($needle1, $singleArray) && in_array($needle2, $singleArray))
              return true;
           else
            continue;
        }
        return false;
    }

and invoke your recursive_array_search like this

if ($this->array_search($schedule->getStart(), $schedule->getDescription(), $pdfArray['rows'])
continue;//Or any other kind of logic you want. At this place you know that description and date staet exist in at your array level
$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();

2 Comments

But having $pdfArray['rows'][$i] as the second parameter only searches the current $i level, which at this state is empty?! And removing [$i] would make the first case in my example also false
check update, I made some changes after reading again your question because is a bit confusing what you want to achieve.
1

Function version:

/** 
 * Find matches for $item into pdfArray.
 * Returns an index array, possibly empty if no matches.
 * @param $item      item to find
 * @param $rows      rows where to search
 */
function findPdfArrayMatches(array $item, array $rows) {
    return array_keys(
  array_filter(
    $rows,
    function ($entry) use ($item) {

      // These are the matching criteria. More than one row may match.

      return $entry['desc'] == $item['desc']
          && $entry['date'] == $item['date']
      ;

    }
  )
);
}

You could do like this, in the loop:

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

$matches = findPdfArrayMatches($item, $pdfArray['rows']);

if (!empty($matches)) {
    ...do something with the matches:
    foreach ($matches as $match) {
        $pdfArray['rows'][$match]['Duplicate'] = true;
    }
}
// Add new item
$pdfArray['rows'][$i] = $item;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.