2

how would you convert this array:

Array
(
    [0] => Array
        (
            [Contact] => Array
                (
                    [number] => 0425 234 634
                )

        )

    [1] => Array
        (
            [Contact] => Array
                (
                    [number] => 2939 492 235
                )

        )

)

into this array

Array
(
    [0] => 0425 234 634
    [1] => 2939 492 235
)

?

7 Answers 7

7

See Set::extract() It uses xpath notation to extract node values from paths in arrays.

$numbers = Set::extract('/Contact/number', $numbers);

Achieve all this in 1 line in far more understandable code than other examples suggested here.

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

1 Comment

+1 for mentioning current usage of Set::extract (xpath as opposed to dot notation)
4

A very dirty method, don't think there is a function to do this for you though.

foreach($array1 as $key => $value) {
    $array2[$key]=$value['contact']['number'];
}

EDIT:

Actually, array_values might be of some help, would be worth testing it against your multi-dimensional array.

5 Comments

values in the mentioned array are in fact arrays themselves thus turning array_values useless in the current context. try it!
It may well be, didn't get chance to test it with a multi-dimensional array :-)
thank you, i tried array_values() there are some interesting ways to flatten arrays in the manual php.net/manual/en/function.array-values.php ill try your solution too, if it works you get a tick ;)
you can use array_shift to flatten your array. Check out my answer below
Use CakePHP's Set::extract function (similar to Set::classicExtract() below) - do this in 1 line of code not 3, and it's far more readable.
4

Since you are using CakePHP, there is an included utility library that does just what you need.

$a = array(
    0 => array(
        'Contact' => array(
                'number' => "0425 234 634"
        )
    ),
    1 => array(
        'Contact' => array(
                'number' => "2939 492 235"
        )
    )
);

$b = Set::classicExtract($a, '{n}.Contact.number');

print_r($b);

And the result is:

Array
(
    [0] => 0425 234 634
    [1] => 2939 492 235
)

1 Comment

Why not the modern Set::extract('/Contact/number', $a)?
2

I've only seen solutions using a seperate array to store the results, this would work just as fine:

<?php
    foreach($numbers as $key => $number) {
        $numbers[$key] = $number['Contact']['number'];
    }
?>

Comments

1

Here you go, fully functional and without any assumptions about your original array :)

<?php
$array = array(
    0 => array(
        'Contact' => array(
            'number' => 123123123
        )
    ),
    1 => array(
        'Contact' => array(
            'number' => 123123123
        )
    ),
    2 => array(
        'Contact' => array(
            'number' => 123123123
        )
    ),
);


function flattenArray(array $arr, &$newArr) {
    while($array = array_shift($arr)) {
        if(is_array($array)) {
            flattenArray($array, $newArr);
        } else {
            $newArr[] = $array;
        }
    }
}

$newArr = array();

foreach($array as $key => $value) {
    flattenArray($value, $newArr);
}

Comments

1
class DeepCollect {
  protected $arr = array();

  public function collect($item, $key) {
    $this->arr[] = $item;
  }

  public static function collect_all($array) {
    $collect = new self;
    array_walk_recursive($array, array($collect, "collect"));
    return $collect->arr;
  }
}

print_r(DeepCollect::collect_all($input_array));

Will work for any nested-array irrespective of key combinations.

Comments

1

This should work also with

Set:extract( "{n}.Contact.number", $a );
Set::extract( "/number", $a );

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.