I have this kind of array
array(1) {
["key,language,text"] => "home,es,casa"
}
Is it possible to parse it and split it to have
array(3) {
['key'] => "home" ,
['language'] => "es" ,
['text'] => "casa"
}
My actual solution is to do the following but I'm pretty sure that I can find a better approach
$test = explode(',', $my_array['key,language,text']);
$my_array['key'] = $test[0];
$my_array['language'] = $test[1];
$my_array['text'] = $test[2];
You can use array_combine to create an array from an array of keys and values, providing the length of each is equal, it will return false if there is a mismatch.
foreach($array as $keys_str => $values_str) {
$keys = explode(",", $keys_str);
$values = explode(",", $values_str);
$kv_array = array_combine($keys, $values);
}
$kv_array would be in the format you're after.
Give it a try..
$arr = array("key,language,text" => "home,es,casa");
$val = explode(",", $arr[key($arr)]);
foreach(explode(",", key($arr)) as $k => $key){
$data[$key] = $val[$k];
}
If you have an array with only 1 entry:
$a = ["key,language,text" => "home,es,casa"];
you could use reset which will return the value of the first array element and key which will return the key of the array element that's currently being pointed to by the internal pointer.
Then use explode and use a comma as the delimiter and use array_combine using the arrays from explode for the keys and the values to create the result.
$result = array_combine(explode(',', key($a)), explode(',', reset($a)));
print_r($result);
That will give you:
array(3) {
["key"]=>
string(4) "home"
["language"]=>
string(2) "es"
["text"]=>
string(4) "casa"
}
This best solution for you :
//this your problem
$array = [
"key,language,text" => "home,es,casa",
"key,language,text" => "home1,es1,casa1"
];
$colms_tmp = 0;
//this your solution, foreach all
foreach($array as $key => $val){
//split your value
$values = explode(",",$val);
//foreach the key (WITH COLMNS), $colm is number of key after explode
foreach(explode(",",$key) as $colm => $the_key){
$result[$colms_tmp][$the_key] = $values[$colm];
}
$colms_tmp++;
}
i haven't try it, but i think this can help you.
Related
How can I convert the string test[1][2][3][4][5] to a multidimensional PHP array like:
array(1 => array(2 => array( 3 => array( 4 => array(5 => array()))));
If I understood your question correctly, you're asking to convert the string "test[1][2][3][4][5]" to array(1 => array(2 => array( 3 => array( 4 => array(5 => array()))));
First of all, people usually use the short array() notation, which is just [].
Second, why use strings, when you can just type
$test[1][2][3][4][5] = [];
to get what you want.
If you really want strings, you can do it in several ways, one of which is:
function makeArrayFromString($string, &$name)
{
$namePosEnd = strpos($string, '['); // name ends when first [ starts
if (!$namePosEnd) return false; // didn't find [ or doesn't start with name
$name = substr($string, 0, $namePosEnd);
$dimensionKeys = [];
$result = preg_match_all('/\[([0-9]+)\]/', $string, $dimensionKeys); // get keys
if (!$result) return false; // no matches for dimension keys
$dimensionKeys = array_reverse($dimensionKeys[1]);
$multiArray = [];
foreach ($dimensionKeys as $key)
{
$key = (int)$key; // we have string keys, turn them to integers
$temp = [];
$temp[$key] = $multiArray;
$multiArray = $temp;
}
return $multiArray;
}
$string = 'test[1][2][3][4][5]';
$name = '';
$multiArray = makeArrayFromString($string, $name);
if ($multiArray === false)
exit('Error creating the multidimensional array from string.');
$$name = $multiArray; // assign the array to the variable name stored in $name
var_dump($test); // let's check if it worked!
Outputs:
array(1) {
[1]=>
array(1) {
[2]=>
array(1) {
[3]=>
array(1) {
[4]=>
array(1) {
[5]=>
array(0) {
}
}
}
}
}
}
Keep in mind that I didn't add any checks if the $name string satisfies the PHP variable naming rules. So you might get an error if you do something like 111onetest[1][2][3][4][5], as variable names in PHP can't start with a number.
At the moment I am doing a foreach over the array, and creating a new array as I go. For example:
$newMap = [];
foreach ($oldMap as $key => $value) {
// Apply some complex logic to $value to extract a string
$newString = my_value_processor($value);
$newkey = $key + $newString;
$newMap[$newKey] = $value;
}
I have the feeling I should be able to accomplish this with array_map(), or possibly array_walk(), and that it would be more efficient, but I can't seem to make it work.
EDIT: In the example above, the code was simplified to show that the $newKey is dependent on $value. The actuality, $value is a sub-array, and I apply some complex logic to it to extract a string. I have updated the example above to demonstrate that.
You may use array_map if you want to modify array values (pay attention that here anonymous function used, that is available from PHP 7)
Modifying array values with array_map
$array = array(
"k1" => "1",
"k2" => "2",
"k3" => "3",
);
$mapFunc = function($item) {
return $item . '_';
};
$newArray = array_map($mapFunc, $array);
var_dump($newArray);
Result:
array(3) {
["k1"]=>
string(2) "1_"
["k2"]=>
string(2) "2_"
["k3"]=>
string(2) "3_"
}
You may use array_reduce if you want to modify array keys or values or both
Modifying array keys with array_reduce
$array = array(
"k1" => "1",
"k2" => "2",
"k3" => "3",
);
$reduceFunc = function($carry, $key) use ($array) {
$carry[$key . '_'] = $array[$key];
return $carry;
};
$newArray = array_reduce(
$array,
$reduceFunc,
[]
);
var_dump($newArray);
Result:
array(3) {
["1_"]=>
string(1) "1"
["2_"]=>
string(1) "2"
["3_"]=>
string(1) "3"
}
But from my point of view it is functional style of programming, that is not typical for php, so i think your foreach approach is better.
Try this code, this code with array_walk().
$newMap = [];
array_walk($oldMap, function ($value,$key) use (&$newMap) {
$newkey = $key + $value + 'blah blah blah';
$newMap[$newkey] = $value;
});
If are you use string as 'blah blah blah' then replace "+"(plus) to"."(dot).
You can try this way,
$oldMap = ['test12' => 'test'];
foreach($oldMap as $key => $value)
{
$oldMap[$key.'_'.$value.'blah blah'] = $value;
unset($oldMap[$key]);
}
var_dump($oldMap);
I have an array.
Array
(
[0] => min_order_level="5"
[1] => max_order_level="10"
[2] => step_order_level="4"
[3] => product_box="9"
)
What I need is
Array
(
[min_order_level] => "5"
[max_order_level] => "10"
[step_order_level] => "4"
[product_box] => "9"
)
I have an idea of doing this using foreach. But without foreach is there any way to do this.
Thanks!
A simple foreach will do..
foreach($arr as $v)
{
list($a,$b)= explode('=',$v);
$new_arr[$a]=(int)trim($b,'"');
}
print_r($new_arr);
Working Demo
Without a foreach as requested on the question..
$new_arr = array();
array_map(function ($v) use (&$new_arr) { list($a,$b)= explode('=',$v); $new_arr[$a]=(int)trim($b,'"'); },$arr);
print_r($new_arr);
Working Demo
The simple foreach() mentioned in one of the answer should be enough, however, if you want to use array functions, you can do:
$new = array_combine(
array_map(function($k){ $ex=explode('=',$k); return $ex[0]; }, $arr)
,
array_map(function($v){ $ex=explode('=',$v); return $ex[1]; }, $arr)
);
The key point here is to break the string at = using explode(), pass all the keys and values separately using array_map() and combine them using array_combine().
DEMO
One line without foreach
$array = [
0 => 'min_order_level="5"',
1 => 'max_order_level="10"',
2 => 'step_order_level="4"',
3 => 'product_box="9"'];
parse_str(implode('&', $array), $result);
var_dump($result);
array(4) {
'min_order_level' =>
string(3) ""5""
'max_order_level' =>
string(4) ""10""
'step_order_level' =>
string(3) ""4""
'product_box' =>
string(3) ""9""
}
Variant with preg_match_all
$string = implode("\n", $array);
preg_match_all('/(.*)="(.*)"/', $string, $matches);
$result = array_combine($matches[1], $matches[2]);
var_dump($result);
To do it without foreach, how about array_walk
$new_array = array();
array_walk($array, 'callback');
function callback($item2, $key)
{
global $new_array;
$parts = explode('=',$item2);
$new_array[$parts[0]]=$parts[1];
}
print_r($new_array);
How can i do an array_merge on an associative array, like so:
Array 1:
$options = array (
"1567" => "test",
"1853" => "test1",
);
Array 2:
$option = array (
"none" => "N/A"
);
So i need to array_merge these two but when i do i get this (in debug):
Array
(
[none] => N/A
[0] => test
[1] => test1
)
try using :
$finalArray = $options + $option .see http://codepad.org/BJ0HVtac
Just check the behaviour for duplicate keys, I did not test this. For unique keys, it works great.
<?php
$options = array (
"1567" => "test",
"1853" => "test1",
);
$option = array (
"none" => "N/A"
);
$final = array_merge($option,$options);
var_dump($final);
$finalNew = $option + $options ;
var_dump($finalNew);
?>
Just use $options + $option!
var_dump($options + $option);
outputs:
array(3) {
[1567]=>
string(4) "test"
[1853]=>
string(5) "test1"
["none"]=>
string(3) "N/A"
}
But be careful when there is a key collision. Here is what the PHP manual says:
The keys from the first array will be preserved. If an array key exists in both arrays, then the element from the first array will be used and the matching key's element from the second array will be ignored.
$final_option = $option + $options;
I was looking to merge two associative arrays together, adding the values together if the keys were the same. If there were keys unique to either array, these would be added into the merged array with their existing values.
I couldnt find a function to do this, so made this:
function array_merge_assoc($array1, $array2)
{
if(sizeof($array1)>sizeof($array2))
{
echo $size = sizeof($array1);
}
else
{
$a = $array1;
$array1 = $array2;
$array2 = $a;
echo $size = sizeof($array1);
}
$keys2 = array_keys($array2);
for($i = 0;$i<$size;$i++)
{
$array1[$keys2[$i]] = $array1[$keys2[$i]] + $array2[$keys2[$i]];
}
$array1 = array_filter($array1);
return $array1;
}
Reference: http://www.php.net/manual/en/function.array-merge.php#90136
when array_merge doesn't work, then simply do
<?php
$new = array();
foreach ($options as $key=>$value) $new[$key] = $value;
foreach ($option as $key=>$value) $new[$key] = $value;
?>
or switch the two foreach loops depending on which array has higher priority
This code could be used for recursive merge:
function merge($arr1, $arr2){
$out = array();
foreach($arr1 as $key => $val1){
if(isset($arr2[$key])){
if(is_array($arr1[$key]) && is_array($arr2[$key])){
$out[$key]= merge($arr1[$key], $arr2[$key]);
}else{
$out[$key]= array($arr1[$key], $arr2[$key]);
}
unset($arr2[$key]);
}else{
$out[$key] = $arr1[$key];
}
}
return $out + $arr2;
}
If arrays having same keys then use array_merge_recursive()
$array1 = array( "a" => "1" , "b" => "45" );
$array2 = array( "a" => "23" , "b" => "33" );
$newarray = array_merge_recursive($array1,$array2);
The array_merge_recursive() wont overwrite, it just makes the value as an array.
I know I'm probably missing something easy, but I have a foreach loop and I'm trying to modify the values of the first array, and output a new array with the modifications as the new values.
Basically I'm starting with an array:
0 => A:B
1 => B:C
2 => C:D
And I'm using explode() to strip out the :'s and second letters, so I want to be left with an array:
0 => A
1 => B
2 => C
The explode() part of my function works fine, but I only seem to get single string outputs. A, B, and C.
Sounds like you want something like this?
$initial = array('A:B', 'B:C', 'C:D');
$cleaned = array();
foreach( $initial as $data ) {
$elements = explode(':', $data);
$cleaned[] = $elements[0];
}
Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself
$arr = array( 0 => 'A:B', 1 => 'B:C', 2 => 'C:D');
// foreach($arr as $val) will not work.
foreach($arr as &$val) { // prefix $val with & to make it a reference to actual array values and not just copy a copy.
$temp = explode(':',$val);
$val = $temp[0];
}
var_dump($arr);
Output:
array(3) {
[0]=>
string(1) "A"
[1]=>
string(1) "B"
[2]=>
&string(1) "C"
}