2

I have an array like

[0] Bert14:50
[1] hello
[2] Sarah14:50
[3] bye
[4] Dennis14:50
[5] hi
[6] wow

I want to reduce it to look like:

[0] Bert14:50
[1] Sarah14:50
[2] Dennis14:50

I've achieved that with this code:

//Doesn't any number exist in the array item? Then remove item
//by first setting it to NULL, and after the loop do some reindexing etc.
foreach($new_str as $item_key => &$item) {
    if (!preg_match('~[0-9]+~', $item)) {
        $item = null;       
    }
}
//Remove null by using unique array...
$new_str = array_values(array_unique($new_str));
//..and then remove first item if it's null
if ($new_str[0] === null) {unset($new_str[0]);}

But why does not this code do not remove items that does not contain 0-9? Why can't I unset a passed by reference value like this?

foreach($new_str as $item_key => &$item) {
    if (!preg_match('~[0-9]+~', $item)) {
       //Nothing seems to happen here. Output of $new_str is same as original 
       //array    
       unset($item); 
    }
}
8
  • 1
    I think you want array_filter(). Commented May 6, 2020 at 14:01
  • aha ok. I'll look it into it! But I still would like the answer on my question because I'm curious. (even if array_filter might be a better solution) Commented May 6, 2020 at 14:05
  • Here's a better example: 3v4l.org/ZSPnD Commented May 6, 2020 at 14:07
  • 2
    Use preg_grep instead $new_str = preg_grep("~\d+~", $new_str); or more precise $new_str = preg_grep("~:\d+$~", $new_str); See 3v4l.org/YSkaI Commented May 6, 2020 at 14:07
  • 1
    I think the point is that &$item is a reference to the value in the array, not the value in the array (with it's own reference). Unsetting $item removes the iteration $item variable reference, not the value (and reference) in the array it points to. 3v4l.org/be7Qo Commented May 6, 2020 at 14:22

1 Answer 1

2

The $item in the foreach is a reference to the value. See this page for an explanation about Unsetting References.

When you unset the reference, you just break the binding between variable name and variable content. This does not mean that variable content will be destroyed.

As pointed out in the comments, you can use unset indexing into the array by the key like unset($new_str[$item_key]); You don't need the reference &$item.

A shorter way to do this could be using preg_grep matching a single digit. You don't need the quantifier + after the character class as you are only detecting if a digit it present.

$new_str = preg_grep("~[0-9]~", $new_str);

Or a bit more precise for the example data, match a digit, colon and a digit:

$new_str = preg_grep("~[0-9]:[0-9]~", $new_str);

Output

Array
(
    [0] => Bert14:50
    [2] => Sarah14:50
    [3] => Dennis14:50
)

Php demo

If you want to reset the keys, you could use array_values($new_str)

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks s lot! Both for explanation and a far better solution with preg_grep!
$new_str = array_values(preg_grep("~[0-9]~", array_unique(explode("\r\n", $check_str)))); One-liner - real cool based on checking a string $check_str which contains \r\n.

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.