9

I'm trying to exclude foreach-loops and refactor them with array functions. I was under the assumption the code below would give me a result with all first items from the source array.

<?php
    $data= [
        0 => [1, 'test1'],
        1 => [2, 'test2'],
        2 => [3, 'test3'],
    ];

    $ids = array_filter($data, function($item) {
        return $item[0];
    });

    var_dump($ids);

But when I var_dump $ids I get the output:

array (size=3)
  0 => 
    array (size=2)
      0 => int 1
      1 => string 'test1' (length=5)
  1 => 
    array (size=2)
      0 => int 2
      1 => string 'test2' (length=5)
  2 => 
    array (size=2)
      0 => int 3
      1 => string 'test3' (length=5)

Why isn't the output:

array (size=3)
  0 => int 1
  1 => int 2
  2 => int 3
4

5 Answers 5

17

array_filter is used for filtering out elements of an array based on whether they satisfy a certain criterion. So you create a function that returns true or false, and test each element of the array against it. Your function will always return true, since every array has a first element in it, so the array is unchanged.

What you're looking for is array_map, which operates on each element in an array by running the callback over it.

<?php
$data= [
    0 => [1, 'test1'],
    1 => [2, 'test2'],
    2 => [3, 'test3'],
];

$ids = array_map(function($item) {
    return $item[0];
}, $data);

var_dump($ids);

As another answer mentions, if all you want to do is extract a single "column", then array_column is a much simpler option.

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

1 Comment

Thanks for clarifying the difference. Somehow filter sounds more logical to me. +1A
10

Try this code

$data= [
        0 => [1, 'test1'],
        1 => [2, 'test2'],
        2 => [3, 'test3'],
    ];

    $ids = array_column($data, 0);
    var_dump($ids);

1 Comment

This is the best answer, it's a shame that it is a code-only answer from a deleted user. This is exactly what array_column() is for.
2

The filter function needs to return a boolean(or any value that can be coerced to true) for each item so that it can be spared. So in your case it is always returning true for every element in the array

To get the result you 'd have to array_walk;

 $data = [
        0 => [1, 'test1'],
        1 => [2, 'test2'],
        2 => [3, 'test3'],
     ];


 array_walk($data, function($value, $key) use ($data){
                  $data[$key] = $value[0];
           })

1 Comment

That looks more complicated than the suggested array_column or array_map. Thanks for the contribution to show array_walk's possibilities. +1
0

the function included in the array_filter must return either true or false. 0 or empty array are converted to FALSE. Non-zero numbers are considered as true.

so if you want to find an item with id 2, you should compare it with 2 like this

<?php
$data= [
    0 => [1, 'test1'],
    1 => [2, 'test2'],
    2 => [3, 'test3'],
];

$ids = array_filter($data, function($item) {
    return $item[0] == 2;
});

var_dump($ids);

output

array(1) {
  [1] =>
  array(2) {
    [0] =>
    int(2)
    [1] =>
    string(5) "test2"
  }
}

Comments

0

Try below code

$data= [
        0 => [1, 'test1'],
        1 => [2, 'test2'],
        2 => [3, 'test3'],
    ];

    $ids = array_map(function($item) {
        return $item[0];
    }, $data);

    var_dump($ids);

1 Comment

Check other answers before posting! It is already posted by @iainn

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.