0

Let's say we have the following dataset:

$data = [
  'Newcastle Upon Tyne, Tyne and Wear, England' => 18,
  'Gateshead, Tyne and Wear, England' => 17,
  'Sunderland, Tyne and Wear, England' => 3,
  ...
];

I want to map through the function and change the keys to look like this:

$data = [
  'Newcastle Upon Tyne' => 18,
  'Gateshead' => 17,
  'Sunderland' => 3,
  ...
];

I thought I might be able to use array_walk like so...

return array_walk($this->_cities, function(&$key, $val) {
  substr( $key, 0, strpos( $key, ',' ) ) = $b;
});

But that produces the error:

 Can't use function return value in write context 

So instead I'm doing it like this:

$cleaned_data = [];
foreach ( $this->_cities as $city => $count )
  $cleaned_data[ substr( $city, 0, strpos( $city, ',' ) ) ] = $count;
return $cleaned_data;

Is it possible to do this using array_walk or a similar function?

Jack Robson
  • 2,184
  • 4
  • 27
  • 50
  • Why are you passing key as reference? `&$key`? Also, how are you calling the function that is returning the values? What is the context it is referring to? – Anthony Nov 08 '18 at 01:21
  • Also, what is `$b`? And why are setting a `substr` to a variable? – Anthony Nov 08 '18 at 01:24
  • You can't use `array_walk`. From the [manual](http://php.net/manual/en/function.array-walk.php): "Only the values of the array may potentially be changed; its structure cannot be altered, i.e., the programmer cannot add, unset or reorder elements. If the callback does not respect this requirement, the behavior of this function is undefined, and unpredictable." – Nick Nov 08 '18 at 01:30
  • Your error `Can't use function return value in write context` comes from assigning a value to a function return here `substr( $key, 0, strpos( $key, ',' ) ) = $b;` you can set `substr`'s return to equal whatever `$b` is. If you could what would bet the point calling the function, if you instantly set it's return value to equal something else, besides the fact that returns are values not variables, it's kin to saying `false = $b` or `'foo' = $b` etc.. – ArtisticPhoenix Nov 08 '18 at 01:42

2 Answers2

0

There are many way's you can do it, one approach could be using explode() and foreach(), another would be using array_walk(). I've added both way's using a demo. Hope it helps :)

<?php

$data = [
  'Newcastle Upon Tyne, Tyne and Wear, England' => 18,
  'Gateshead, Tyne and Wear, England' => 17,
  'Sunderland, Tyne and Wear, England' => 3,
];

$result = [];
foreach($data as $key=>$value){
    $result[explode(',',$key)[0]] = $value;
}

print_r($result);

DEMO: https://3v4l.org/1QQna

OR using array_walk()

<?php

$data = [
  'Newcastle Upon Tyne, Tyne and Wear, England' => 18,
  'Gateshead, Tyne and Wear, England' => 17,
  'Sunderland, Tyne and Wear, England' => 3,
];

$result = [];
array_walk($data, function (&$value,$key) use (&$result) {
    $splitted = explode(",",$key);
    $result[ $splitted[0] ] = $value;
});

print_r($result);

DEMO: https://3v4l.org/YWYLY

A l w a y s S u n n y
  • 36,497
  • 8
  • 60
  • 103
0

Im not sure if you can use modify array keys by passing as reference. But you can do it like this:

$data = [
  'Newcastle Upon Tyne, Tyne and Wear, England' => 18,
  'Gateshead, Tyne and Wear, England' => 17,
  'Sunderland, Tyne and Wear, England' => 3,
];
foreach($data as $key => $val) {
  unset($data[$key]);
  $data[substr($key, 0, strpos($key, ',' ))] = $val;
};

echo "<pre>"; print_r($data);
ACD
  • 1,431
  • 1
  • 8
  • 24