1

Can anybody explain how to take this array:

array(
    'Anto' => 25,
    'Filip' => 22,
    'Marko' => 17,
    'Josip' => 23,
    'Igor' => 24,
    'Ivan' => 23,
);

And map it like this:

array(
    17 => [1, 'Marko'],
    22 => [1, 'Filip'],
    23 => [2, 'Josip', 'Ivan'],
    24 => [1, 'Igor'],
    25 => [1, 'Anto'],
);

The new array contains keys that are the age (from the value of the initial array) and the value is an array containing the number of people with the same age followed by all names with the same age.

Sam
  • 20,096
  • 2
  • 45
  • 71
fvukovic
  • 699
  • 1
  • 7
  • 14
  • Try something yourself, we are not here to write code for you. For starters look at a `foreach` loop, that could help you maybe. – Nytrix Jul 12 '16 at 18:47
  • look at this answer, it may help you (you only need to add the counter) http://stackoverflow.com/a/12706456/1437934 – Gonzalo.- Jul 12 '16 at 18:48
  • [`array_reduce()`](http://php.net/manual/en/function.array-reduce.php) fits better for this kind of problem. Unfortunately, both [`array_map()`](http://php.net/manual/en/function.array-map.php) and [`array_reduce()`](http://php.net/manual/en/function.array-reduce.php) ignore the array keys completely and this makes them unsuitable for your needs. A simple [`foreach`](http://php.net/manual/en/control-structures.foreach.php) is probably the best solution here. – axiac Jul 12 '16 at 19:06

2 Answers2

1

foreach is going to be simpler than array_map() here. I also make use of array_key_exists() and ksort() to make things cleaner. See my documented example below.


Example:

// Data.
$initialArray = array(
    'Anto' => 25,
    'Filip' => 22,
    'Marko' => 17,
    'Josip' => 23,
    'Igor' => 24,
    'Ivan' => 23,
);
$newArray = array();

// Loop.
foreach($initialArray as $name => $age) {
    if(!array_key_exists($age, $newArray)) {
        // Initialize this age in the new array with empty counter.
        $newArray[$age] = array(0);
    }

    // Increment the counter.
    $newArray[$age][0]++;

    // Append the name.
    $newArray[$age][] = $name;
}

// Sort by age.
ksort($newArray);

// Dump.
print_r($newArray);

Output:

Array
(
    [17] => Array
        (
            [0] => 1
            [1] => Marko
        )

    [22] => Array
        (
            [0] => 1
            [1] => Filip
        )

    [23] => Array
        (
            [0] => 2
            [1] => Josip
            [2] => Ivan
        )

    [24] => Array
        (
            [0] => 1
            [1] => Igor
        )

    [25] => Array
        (
            [0] => 1
            [1] => Anto
        )

)

This is just one of many ways to do this. I strongly suggest reading more into the foreach control structure so that you grasp the concept fully...it'll be necessary moving forward as a programmer!

You could also do this by adding the counter at the end of your logic. First, you would go through and sort each name into an array based on their age. Then, you would go through and prepend the count($names) to the beginning of the $names array at $age index.

Sam
  • 20,096
  • 2
  • 45
  • 71
0

You can use array_walk for this. Here you go:

$array = [
    'John' => 25,
    'Tony' => 25,
    'Anto' => 25,
    'Filip' => 22,
    'Marko' => 17,
    'Josip' => 23,
    'Igor' => 24,
    'Ivan' => 23,
];

$ages = [];

array_walk($array, function ($age, $name) use (&$ages) {
    // Does the age already exist? If so, we'll increment
    // the count, otherwise we'll initialize it to one.
    array_key_exists($age, $ages) ? $ages[$age][0]++ : $ages[$age][0] = 1;

    $ages[$age][] = $name;
});

var_dump($ages);

Output:

array:5 [▼
  25 => array:4 [▼
    0 => 3
    1 => "John"
    2 => "Tony"
    3 => "Anto"
  ]
  22 => array:2 [▼
    0 => 1
    1 => "Filip"
  ]
  17 => array:2 [▼
    0 => 1
    1 => "Marko"
  ]
  23 => array:3 [▼
    0 => 2
    1 => "Josip"
    2 => "Ivan"
  ]
  24 => array:2 [▼
    0 => 1
    1 => "Igor"
  ]
]
Steve Bauman
  • 8,165
  • 7
  • 40
  • 56