0

I have following code that removes adjacent duplicates from the $myArray

<?php
 $myArray = array(
                    0 => 0,
                    1 => 0,
                    2 => 1,
                    5 => 1,
                    6 => 2,
                    7 => 2,
                    8 => 2,
                    9 => 0,
                    10 => 0,
                );

            $previtem= NULL;
            $newArray = array_filter(
                $myArray,
                function ($currentItem) use (&$previtem) {
                    $p = $previtem;
                    $previtem= $currentItem;
                    return $currentItem!== $p ;
                }
            );

echo "<pre>";
print_r($newArray);
?>

It works perfectly fine, but I have to change a condition bit for value 2. That means for other values we can pick first occurrence and ignore the others. But for 2, we need to pick last occurrence and ignore others.

So required output is

Array
(
    [0] => 0 //first occurrence of 0 in $myArray
    [2] => 1 //first occurrence of 1 in $myArray
    [8] => 2 //last occurrence of 2 in the $myArray
    [9] => 0 //first occurrence of 0 in $myArray
)

How to modify my code to achieve above result??

In reality I have multidimensional array, but for better explanation I have used single dimensional array here in the question.

UPDATE My actual array is

$myArray = array(
        0 => array("Value"=>0, "Tax" => "11.00"),
        1 => array("Value"=>0, "Tax" => "12.00"),
        2 => array("Value"=>1, "Tax" => "13.00"),
        5 => array("Value"=>1, "Tax" => "14.00"),
        6 => array("Value"=>2, "Tax" => "15.00"),
        7 => array("Value"=>2, "Tax" => "16.00"),
        8 => array("Value"=>2, "Tax" => "17.00"),
        9 => array("Value"=>0, "Tax" => "18.00"),
        10 => array("Value"=>0, "Tax" => "19.00"),
    );

And my actual code

$previtem= NULL;
$newArray = array_filter(
    $myArray,
    function ($currentItem) use (&$previtem) {
        $p["Value"] = $previtem["Value"];
        $previtem["Value"] = $currentItem["Value"];
        return $currentItem["Value"]!== $p["Value"] ;
    }
);

Thanks

2 Answers 2

1

This should do what you are looking for.

function array_filter($a) {
$na = array();
$first = true;
$p = null;
$wantlast = false;
foreach ($a as $v) {
    if ($wantlast) {
        ($v != $p) ? $na[] = $p: null;
    }
    $wantlast = ($v == 2) ? true : false;
    if (!$wantlast) {
        (($v != $p) || ($first))? $na[] = $v : null;
    }
    $p = $v;
    $first = false;
}
return $na;
}
Sign up to request clarification or add additional context in comments.

5 Comments

adjusted to match function name to that used by WatsMyName
Thanks I will check and let you know
It changes key which I don't want to change.
I sorted this out. Thanks for the working solution. I will accept your solution because your solution worked perfectly fine with multidimensional array.
Thank you. I felt that a stand alone function should better allow you to modify to suit your needs - particularly in light of the fact that your example was a simplified from the real use case - sorting an array. In the case of not modifying the key, update the foreach to "foreach (a as $k => $v)" - record the key in the same places, and use it when storing.
1
$myArray = array(
        0 => 0,
        1 => 0,
        2 => 1,
        5 => 1,
        6 => 2,
        7 => 2,
        8 => 2,
        9 => 0,
        10 => 0,
    );

$previtem= NULL;
$newArray = array_filter(
    $myArray,
    function ($currentItem, $key) use (&$previtem,$myArray) {
        $p = $previtem;
        if($currentItem != 2){
            $previtem = $currentItem;
        }else{
            $lastkey = array_search(2,(array_reverse($myArray, true)));
            if($key != $lastkey)
                $currentItem = $previtem;
        }
        return $currentItem!== $p ;
    }, ARRAY_FILTER_USE_BOTH
);

echo "<pre>";
print_r($newArray);

2 Comments

Thanks! Will check this
What to do in case of multidimensional array?? Like in update in my post above

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.