9

I have an array like this:

$a = array(
    0 => array('type' => 'bar', 'image' => 'a.jpg'),
    1 => array('type' => 'food', 'image' => 'b.jpg'),
    2 => array('type' => 'bar', 'image' => 'c.jpg'),
    3 => array('type' => 'default', 'image' => 'd.jpg'),
    4 => array('type' => 'food', 'image' => 'e.jpg'),
    5 => array('type' => 'food', 'image' => 'f.jpg'),
    6 => array('type' => 'food', 'image' => 'h.jpg')
)

How do I figure out unique type values (which would be food, bar and default)? I could iterate through the array in a foreach loop but is there a better way doing it?

Krutik Jayswal
  • 3,165
  • 1
  • 15
  • 38
shikhar.ja
  • 457
  • 1
  • 4
  • 11

5 Answers5

18

In PHP >= 5.3 with the use of anonymous functions:

$unique_types = array_unique(array_map(function($elem){return $elem['type'];}, $a));

For previous versions you can declare a separate function:

function get_type($elem)
{
    return $elem['type'];
}

$unique_types = array_unique(array_map("get_type", $a));
omma2289
  • 54,161
  • 8
  • 64
  • 68
17

Using PHP >= 5.5, you could do:

$ar = array_unique(array_column($a, 'type'));

print_r($ar):

Array ( 
    [0] => bar 
    [1] => food 
    [3] => default 
)

http://php.net/manual/en/function.array-column.php

http://php.net/manual/en/function.array-unique.php

Mark Miller
  • 7,442
  • 2
  • 16
  • 22
  • Not sure why this has +5 upvotes, it is a clever solution, not very much straight forward. – Ryan Aug 29 '14 at 04:42
  • 3
    @true How could this have been more `straight forward`? This looks like as simple as it gets. Using the updated functionalities available in newer versions of a language should be appreciated rather than getting confused about. – Hanky Panky Aug 29 '14 at 04:43
  • For 1. Having to look up what the `array_*` do, what they return, if they modify the array by reference..etc. It is just a clever solution, not very much else to say here. Please don't take it personal. – Ryan Aug 29 '14 at 04:44
  • So if someone has to look up why shouldn't they? It's like using mud buckets to cool water in 21st century just for the reason that I don't want to read power specifications of my Fridge that I just bought yesterday :) Plus even the OP mentioned they want are not looking for an old school method. – Hanky Panky Aug 29 '14 at 04:46
  • And nope nothing personal, its just a small discussion about whether to use newer tools available in the newer versions of language, you're entitled to your opinion as much as anyone else is, so nothing wrong there :) – Hanky Panky Aug 29 '14 at 04:49
  • @Mark M - Using language constructs rather than extensions would indicate you know the language .. `foreach, isset` are language constructs, `array_*` are extension functions that require implicit knmowledge – Ryan Aug 29 '14 at 04:52
  • This is a neat solution but I'm using php 5.4, so can't really use this one. – shikhar.ja Aug 29 '14 at 13:01
3

An old fashioned way without using the fancy array_* functions. This way is simple and easy to understand. You aren't left wondering what is happening because it so straightforward.

$a = array(
    0 => array('type' => 'bar', 'image' => 'a.jpg'),
    1 => array('type' => 'food', 'image' => 'b.jpg'),
    2 => array('type' => 'bar', 'image' => 'c.jpg'),
    3 => array('type' => 'default', 'image' => 'd.jpg'),
    4 => array('type' => 'food', 'image' => 'e.jpg'),
    5 => array('type' => 'food', 'image' => 'f.jpg'),
    6 => array('type' => 'food', 'image' => 'h.jpg')
);

$types = array();

foreach($a as $key => $type) {
        if(! isset($types[$type['type']]))
                $types[$type['type']] = $type['type'];
}

var_dump($types);
Ryan
  • 14,392
  • 8
  • 62
  • 102
  • Actually, one of the fastest answers due to any of `array_*` function provided does input array copying. Language constructs are better there. – BlitZ Aug 29 '14 at 04:52
  • That is interesting that you mention language constructs, because I just posted a comment about language constructs in one of the other answers before I read your comment. – Ryan Aug 29 '14 at 04:53
0

try this

$uniqueA = array_unique($a, "type");
// then to output the array just type
print_r($uniqueA);
Dody
  • 19
  • 5
0

You could also use array_reduce.

This only doesn't work if the values of the attribute are an array or object, because those can't be set as the key of an array.

function array_unique_attr($arr, $key) {

    return array_keys( array_reduce($arr, function($newArr, $event) {

        $newArr[$key] = true;
        return $newArr;

    }, []) );

}

$unique_types = array_unique_attr($a, 'type');
blablabla
  • 1,468
  • 15
  • 17