Reputation:
I have an array:
[ 0 ] => 3000mAh battery
[ 1 ] => charges 1 smartphone
[ 2 ] => input: 5W (5V, 1A) micro USB port
[ 3 ] => output: Micro USB cable: 7.5W (5V, 1.5A)
[ 4 ] => recharge time 3-4 hours
[ 5 ] => includes Micro USB cable
[ 6 ] => 1-Year Limited Warranty
I want to remove these keys and put the part of the string that is already in value. The final result that i want is:
[ battery ] => 3000mAh
[ charges ] => 1 smartphone
[ input ] => 5W (5V, 1A) micro USB port
[ output ] => Micro USB cable: 7.5W (5V, 1.5A)
[ recharge ] => time 3-4 hours
[ includes ] => Micro USB cable
[ Warranty ] => 1-Year Limited
There is three condition here:
1) if string have : then take text before first : and put it in key example:
[ 2 ] => input: 5W (5V, 1A) micro USB port
[ input ] => 5W (5V, 1A) micro USB port
2) if string begins with number take last word of string and put it like key:
[ 0 ] => 3000mAh battery
[ battery ] => 3000mAh
3) if string begins with letter take first word of string and put it like key:
[ 1 ] => charges 1 smartphone
[ charges ] => 1 smartphone
This is my code that solved first condition, can you help me how i can do the rest?
$new_array= array_reduce($old_array, function ($c, $v){
preg_match('/^([^:]+):\s+(.*)$/', $v, $m);
if(!empty($m[1])){
return array_merge($c, array($m[1] => $m[2]));}
else{
return array();
}
},[]);
Upvotes: 1
Views: 52
Reputation: 57131
Rather than use regexes - just using explode()
can break down the items quicker and also (IMHO) clearer. This first looks to split it with :
, if this produces a result, then use the first item as the key and the rest as the content. If this fails then use a space and just check which version to use (using is_numeric()
on the first character)...
$output = [];
foreach ( $data as $item ) {
$split = explode(":", $item );
if ( count($split) > 1 ) {
$key = array_shift($split);
$join = ":";
}
else {
$split = explode(" ", $item);
if ( strtolower($split[count($split)-1]) == "warranty" ||
is_numeric($item[0]) ){
$key = array_pop($split);
}
else {
$key = array_shift($split);
}
$join = " ";
}
$output[$key] = implode($join, $split);
}
print_r($output);
Upvotes: 1
Reputation: 163477
You could check the first characters by using ctype_alpha or is_numeric. To check for a :
you could use explode and check if the count is greater than 1.
To write the value, you could use implode with a space as the glue.
$result = [];
foreach ($items as $item) {
$res = explode(':', $item);
if (count($res) > 1) {
$key = $res[0];
array_shift($res);
$result[$key] = implode(':', $res);
continue;
}
if (is_numeric($item[0])) {
$parts = (explode(' ', $item));
$key = array_pop($parts);
$result[$key] = implode(' ', $parts);
continue;
}
if (ctype_alpha ($item[0])) {
$parts = explode(' ', $item);
$key = array_shift($parts);
$result[$key] = implode(' ', $parts);
}
}
print_r($result);
Upvotes: 1