user3289328
user3289328

Reputation: 67

Count unique rows of data based on the values in two columns

I have a multidimensional array like below and I want to create another array which shows the unique number of users per city.

Array
(
    [0] => Array
        (
            [id] => 1
            [city] => Melbourne
            [date_added] => 1435852550
            [user_name] => user_1
        )

    [1] => Array
        (
            [id] => 2
            [city] => Melbourne
            [date_added] => 1435852550
            [user_name] => user_1
        )

    [2] => Array
        (
            [id] => 3
            [city] => Sydeny
            [date_added] => 1435852550
            [user_name] => user_2
        )

    [3] => Array
        (
            [id] => 4
            [city] => Perth
            [date_added] => 1435852550
            [user_name] => user_3
        )
    [4] => Array
        (
            [id] => 5
            [city] => Perth
            [date_added] => 1435852550
            [user_name] => user_4
        )
)

What I am trying to get is the unique number of users per city like the below:

Array
(
    [Melbourne] => 1
    [Sydeny] => 1
    [Perth] => 2
)

Upvotes: 0

Views: 2042

Answers (3)

mickmackusa
mickmackusa

Reputation: 47992

@LF00's answer is looping just twice and using a nested set of associative keys to group the data. I recommend this approach over any other approach which calls in_array().

The functional-style version of @LF00's answer would be:

Code: (Demo)

var_export(
    array_map(
        'count',
        array_reduce(
            $array,
            function($result, $row) {
                $result[$row['city']][$row['user_name']] = true;
                return $result;
            }
        )
    )
);

@LF00's answer could be more concise in its call of count() in array_map().

Code: (Demo)

$result = [];
foreach ($array as $row) {
    $result[$row['city']][$row['user_name']] = true;
}
var_export(array_map('count', $result));

Upvotes: 0

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

The solution using array_reduce function:

// $arr is your initial array

$hash = [];
$counts = array_reduce($arr, function($r, $a) use(&$hash){
    $hash_str = $a['city'] .'|'. $a['user_name'];
    if (!in_array($hash_str, $hash)) {
        $hash[] = $hash_str;
        (!isset($r[$a['city']]))? $r[$a['city']] = 1 : $r[$a['city']] += 1;
    }
    return $r;
}, []);

print_r($counts);

Upvotes: 0

LF-DevJourney
LF-DevJourney

Reputation: 28559

use the city as index, and array user_names array as value, then map the value to lentgth of the value.

foreach($array as $v)
{
  $temp[$v['city']][$v['user_name']] = 1;
}
$result = array_map(function($v){return count($v);}, $temp);

Upvotes: 1

Related Questions