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.

3
  • Try something yourself, we are not here to write code for you. For starters look at a foreach loop, that could help you maybe. Commented Jul 12, 2016 at 18:47
  • look at this answer, it may help you (you only need to add the counter) stackoverflow.com/a/12706456/1437934 Commented Jul 12, 2016 at 18:48
  • array_reduce() fits better for this kind of problem. Unfortunately, both array_map() and array_reduce() ignore the array keys completely and this makes them unsuitable for your needs. A simple foreach is probably the best solution here. Commented Jul 12, 2016 at 19:06

2 Answers 2

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.

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

Comments

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"
  ]
]

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.