How do I cast a string to an array - php

So as you can see below I have an array that I get from an ajax request.. Now is my question how can I use the [name] as an array? The arrays below are two different arrays
Changing the arrays below is done in PHP
So this:
(
[name] => template[options][4892][is_delete]
[value] => 1
)
(
[name] => template[options][4892][name]
[value] => just_a_name
)
Into this
(
[template] => (
[options] => (
[4892] => (
name => just_a_name,
is_delete => 1
)
)
)
)
Edited: changed value to is_delete
Edit2: changed some things to make it more clear
Hope this is clear enough

$data = [
[
'name' => 'template[options][4892][is_delete]',
'value' => 1
],
[
'name' => 'template[options][4892][name]',
'value' => 'name'
]
];
$parsedData = [];
foreach ($data as $item) {
parse_str($item['name'] . '=' . $item['value'], $out);
$parsedData = array_replace_recursive($parsedData, $out);
}
print_r($parsedData);
result:
Array(
[template] => Array(
[options] => Array(
[4892] => Array(
[is_delete] => 1
[name] => name
)
)
)
)

Related

How to merge two array if one item exist in both array?

I want to expand my city array with post code value.
If the city_postcode array contain city array name record then push postcode value into city array. That's what i want to achive somehow.
city array:
Array
(
[0] => Array
(
[id] => 1
[city] => Budapest
[population] => 1700000
)
[1] => Array
(
[id] => 2
[city] => Szeged
[population] => 160000
)
)
city_postcode array:
Array
(
[0] => Array
(
[name] => Budapest
[post_code] => 12345
)
[1] => Array
(
[name] => Szeged
[post_code] => 33356
)
)
The result I want:
Array
(
[0] => Array
(
[id] => 1
[city] => Budapest
[population] => 1700000
[post_code] => 12345
)
[1] => Array
(
[id] => 2
[city] => Szeged
[population] => 160000
[post_code] => 33356
)
)
If you can rely on the cities and post codes to be equal in length and sorted, you could just do something like this:
<?php
$cities = array(
array("id"=>1,"city"=>"Budapest","Population"=>"1700000"),
array("id"=>2,"city"=>"Szeged","Population"=>"160000")
);
$cityPostCode = array(
array("name"=>"Budapest","post_code"=>12345),
array("name"=>"Szeged","post_code"=>33356)
);
for($i = 0; $i < count($cities); $i++){
$cities[$i]['post_code'] = $cityPostCode[$i]['post_code'];
}
print_r($cities);
Other wise you could do something more dyanmic like:
function _parsePostCode($targetName,$targetArr){
foreach($targetArr as $el){
if($el['name'] == $targetName){
return $el['post_code'];
}
}
return false;
}
for($i = 0; $i < count($cities); $i++){
$cities[$i]['post_code'] = _parsePostCode($cities[$i]['city'],$cityPostCode);
}
print_r($cities);
As an alternative you can use 'reference' PHP in foreach loop as follows
$city = array(
0 => array(
'id' => 1,
'city' => "Budapest",
'population' => 1700000
),
1 => array(
'id' => 2,
'city' => "Szeged",
'population' => 160000
)
);
$city_postcode = array(
0 =>array(
'name' => 'Budapest',
'post_code' => 12345
),
1 => array(
'name' => 'Szeged',
'post_code' => 33356
)
);
foreach ($city as $ckey => &$cval) {
$cval['post_code'] = $city_postcode[$ckey]['post_code'];
}
unset($cval);
var_dump($city);
You can use this simple approach :
<?php
$city = array(
0 => array(
'id' => 1,
'city' => "Budapest",
'population' => 1700000
),
1 => array(
'id' => 2,
'city' => "Szeged",
'population' => 160000
)
);
$city_postcode = array(
0 => array(
'name' => 'Budapest',
'post_code' => 12345
),
1 => array(
'name' => 'Szeged',
'post_code' => 33356
)
);
function apply_post_code(&$item, $key, $postcode)
{
$item['post_code'] = $postcode[ $key ][ 'post_code' ];
}
array_walk($city, 'apply_post_code', $city_postcode);
var_dump($city);
Note that the $city variable has been passes by reference

add or move key and value to first position in multidimensional array

I have the following array, we'll call it $arr and I have prepared a sample array. I need to manipulate the path $arr['svg'] to have a specific key and value always at index 0 position. This is a sample data-set and depending on the data I'm working with the key's and values are not fixed, however the main point is to always have the title array (key and value) at the top of the svg array.
$arr = array("svg" =>
array(
0 => array("#style" => "overflow:visible", "#xlink:href" => "test.png"),
1 => array("g" => "", "#id" => "Layer_2"),
2 => array("g" => "", "#id" => "Layer_3"),
3 => array("title" => "test")
),
"#version" => 1.2,
"#baseProfile" => "tiny-ps",
"#id" => "Layer_1",
"#xmlns" => "http://www.w3.org/2000/svg"
);
I am trying to achieve two things under the array path $arr['svg']
If the array key title exists in $arr['svg'] and it is not in index 0 position
then move it to index 0 of $arr['svg'] and shift everything else
down.
If the array key title DOES NOT exist in $arr['svg'] then add it array('title' =>
'test') to index 0 position of $arr['svg'] and shift
everything else down.
The expected output of $arr will be like so:
Array
(
[svg] => Array
(
[0] => Array
(
[title] => test
)
[1] => Array
(
[#style] => overflow:visible;
[#xlink:href] => test.png
)
[2] => Array
(
[g] =>
[#id] => Layer_2
)
[3] => Array
(
[g] =>
[#id] => Layer_3
)
)
[#version] => 1.2
[#baseProfile] => tiny-ps
[#id] => Layer_1
[#xmlns] => http://www.w3.org/2000/svg
)
I am trying to use this function to achieve this but it seems this function only works from the root array position $arr, not within a specific path $arr['svg']. If it can be modified to work within a specific path that would hopefully solve the issue.
//source: https://gist.github.com/wpscholar/0deadce1bbfa4adb4e4c
function push_at_to_associative_array($array, $key, $new ){
$keys = array_keys( $array );
$index = array_search( $key, $keys, true );
$pos = false === $index ? count( $array ) : $index + 1;
$array = array_slice($array, 0, $pos, true) + $new + array_slice($array, $pos, count($array) - 1, true);
return $array;
}
Usage:
$title = array("title" => "test');
$arr = push_at_to_associative_array($arr, 'svg', $title);
process the svg array into a new one setting [0] to the default title if we later find a title, replace svg[0]['title'] with the found one, then finally replace the original svg part of the array with the new one.
$arr = [
"svg" =>
[
["#style" => "overflow:visible", "#xlink:href" => "test.png"],
["g" => "", "#id" => "Layer_2"],
["g" => "", "#id" => "Layer_3"],
["title" => "Fred"]
],
"#version" => 1.2,
"#baseProfile" => "tiny-ps",
"#id" => "Layer_1",
"#xmlns" => "http://www.w3.org/2000/svg"
];
function push_at_to_associative_array(&$arr)
{
$new_svg = [];
foreach ($arr['svg'] as $key => $svg){
if ( $key == 0){
$new_svg[] = ['title'=>'test'];
}
if ( !array_key_exists('title', $svg) ){
$new_svg[] = $svg;
} else {
# amend title
$new_svg[0]['title'] = $svg['title'];
}
}
$arr['svg'] = $new_svg;
}
push_at_to_associative_array($arr);
print_r($arr);
RESULTS
Array
(
[svg] => Array
(
[0] => Array
(
[title] => Fred
)
[1] => Array
(
[#style] => overflow:visible
[#xlink:href] => test.png
)
[2] => Array
(
[g] =>
[#id] => Layer_2
)
[3] => Array
(
[g] =>
[#id] => Layer_3
)
)
[#version] => 1.2
[#baseProfile] => tiny-ps
[#id] => Layer_1
[#xmlns] => http://www.w3.org/2000/svg
)
And if you run it without a title in the array
$arr = [
"svg" =>
[
["#style" => "overflow:visible", "#xlink:href" => "test.png"],
["g" => "", "#id" => "Layer_2"],
["g" => "", "#id" => "Layer_3"]
],
"#version" => 1.2,
"#baseProfile" => "tiny-ps",
"#id" => "Layer_1",
"#xmlns" => "http://www.w3.org/2000/svg"
];
function push_at_to_associative_array(&$arr)
{
$new_svg = [];
foreach ($arr['svg'] as $key => $svg){
if ( $key == 0){
$new_svg[] = ['title'=>'test'];
}
if ( !array_key_exists('title', $svg) ){
$new_svg[] = $svg;
} else {
# amend title
$new_svg[0]['title'] = $svg['title'];
}
}
$arr['svg'] = $new_svg;
}
push_at_to_associative_array($arr);
print_r($arr);
RESULT
Array
(
[svg] => Array
(
[0] => Array
(
[title] => test
)
[1] => Array
(
[#style] => overflow:visible
[#xlink:href] => test.png
)
[2] => Array
(
[g] =>
[#id] => Layer_2
)
[3] => Array
(
[g] =>
[#id] => Layer_3
)
)
[#version] => 1.2
[#baseProfile] => tiny-ps
[#id] => Layer_1
[#xmlns] => http://www.w3.org/2000/svg
)
An easy solution would be to do something like this:
function fix_array( $array ) {
$svg_title_index = array_key_first(
array_filter(
$array['svg'],
fn($item) => isset($item['title'])
)
);
if (! $svg_title_index) {
array_unshift($array['svg'], ['title' => 'test']);
} elseif($svg_title_index > 0) {
$value = $array['svg'][$svg_title_index];
unset($array['svg'][$svg_title_index]);
array_unshift($array['svg'], $value);
}
return $array;
}
/* CASE 1 - SVG EXISTS BUT IS NOT FIRST */
$array = [
'svg' => [
[
'#style' => 'overflow:visible;',
'##xlink:href' => 'test.png'
],
[
'title' => 'some existing title',
],
],
'#version' => '1.2',
'#baseProfile' => 'tiny-ps',
'#id' => 'Layer_1',
'#xmlns' => 'http://www.w3.org/2000/svg'
];
print_r(fix_array( $array ));
/* CASE 2 - SVG DOES NOT EXIST */
$array = [
'svg' => [
[
'#style' => 'overflow:visible;',
'##xlink:href' => 'test.png'
]
],
'#version' => '1.2',
'#baseProfile' => 'tiny-ps',
'#id' => 'Layer_1',
'#xmlns' => 'http://www.w3.org/2000/svg'
];
print_r(fix_array( $array ));
You can see it in action here
Ok so OP want's to move the array with the title attribute to the start of the array or insert a test value if it doesn't exist.
The below function should achieve this. It might not be the most beautiful or effient but it should put you on the right track.
function order_svg_title( array $input, ?string $default_title ) {
$position = null;
// Find position of existing title (if exists).
foreach( $input[ 'svg' ] as $key => $value ) {
if ( isset( $value[ 'title' ] ) && $key !== 0 ) {
$position = $key;
}
}
// Doesn't already exist, add default title (if not null).
if ( is_null( $position ) ) {
array_unshift( $input[ 'svg' ], array( 'title' => $default_title ) );
}
// Title exists but it's in the wrong position.
else {
$value = $input[ 'svg' ][ $position ];
unset( $input[ 'svg' ][ $position ] );
array_unshift( $input[ 'svg' ], $value );
}
return $input;
}
So for this example usage would be...
$arr = array(
"svg" => array(
array(
"#style" => "overflow:visible",
"#xlink:href" => "test.png"
),
array(
array("g" => "", "#id" => "Layer_2"),
array("g" => "", "#id" => "Layer_3")
)
),
"#version" => 1.2,
"#baseProfile" => "tiny-ps",
"#id" => "Layer_1",
"#xmlns" => "http://www.w3.org/2000/svg"
);
$new_arr = order_svg_title( $arr, 'test' );
Would return:
Array
(
[svg] => Array
(
[0] => Array
(
[title] => test
)
[1] => Array
(
[#style] => overflow:visible
[#xlink:href] => test.png
)
[2] => Array
(
[0] => Array
(
[g] =>
[#id] => Layer_2
)
[1] => Array
(
[g] =>
[#id] => Layer_3
)
)
)
[#version] => 1.2
[#baseProfile] => tiny-ps
[#id] => Layer_1
[#xmlns] => http://www.w3.org/2000/svg
)
Now with an existing title:
$arr = array(
"svg" => array(
array(
"#style" => "overflow:visible",
"#xlink:href" => "test.png"
),
array(
array("g" => "", "#id" => "Layer_2"),
array("g" => "", "#id" => "Layer_3")
),
array(
"title" => "In the wrong position. I should be moved."
)
),
"#version" => 1.2,
"#baseProfile" => "tiny-ps",
"#id" => "Layer_1",
"#xmlns" => "http://www.w3.org/2000/svg"
);
$new_arr = order_svg_title( $arr, 'test' );
Would return:
Array
(
[svg] => Array
(
[0] => Array
(
[title] => In the wrong position. I should be moved.
)
[1] => Array
(
[#style] => overflow:visible
[#xlink:href] => test.png
)
[2] => Array
(
[0] => Array
(
[g] =>
[#id] => Layer_2
)
[1] => Array
(
[g] =>
[#id] => Layer_3
)
)
)
[#version] => 1.2
[#baseProfile] => tiny-ps
[#id] => Layer_1
[#xmlns] => http://www.w3.org/2000/svg
)

find duplicates value with their keys

My array is like this,
$options = Array
(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[1] => Array
(
[value] => 2341
[label] => Suisses
)
[2] => Array
(
[value] => 143
[label] => Nokia
)
[3] => Array
(
[value] => 2389
[label] => 3D Pop Art
)
)
and i want output as,
Array(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[2] => Array
(
[value] => 143
[label] => Nokia
)
)
Can anyone suggest me in this.
You can try something like this:
$options = [
0 => [
'value' => 180,
'label' => 'Nokia'
],
1 => [
'value' => 2341,
'label' => 'Suisses'
],
2 => [
'value' => 143,
'label' => 'Nokia'
],
3 => [
'value' => 2389,
'label' => '3D Pop Art'
],
];
$labels = [];
$duplicates = [];
foreach ($options as $option) {
if (!empty($duplicates[$option['label']])) {
$duplicates[$option['label']][] = $option;
}
if (empty($labels[$option['label']])) {
$labels[$option['label']] = $option;
} else {
$duplicates[$option['label']] = [
$labels[$option['label']],
$option
];
}
}
It seems you are looking for group by 'label'
foreach($options as $v){
$c[$v['label']][] = $v['value'];
}
print_r($c);
Working example : https://3v4l.org/62dv0
The array_filter() function is what you are looking for:
<?php
$data = [
[
'value' => 180,
'label' => "Nokia"
],
[
'value' => 2341,
'label' => "Suisses"
],
[
'value' => 143,
'label' => "Nokia"
],
[
'value' => 2389,
'label' => "3D Pop Art"
]
];
$output = [];
array_walk($input, function($entry) use (&$output) {
$output[$entry['label']][] = $entry;
});
print_r(
array_filter(
$output,
function($entry) {
return count($entry) > 1;
}
)
);
The output obviously is:
Array
(
[Nokia] => Array
(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[1] => Array
(
[value] => 143
[label] => Nokia
)
)
)
That output slightly differs from the one suggested by you. But it has the advantage that you can tell entries apart by the doubled label.

PHP : How to make parallel arrays from multidimentional array

I have this type of array
$arr = array(
0 => array(
0 => array(
'name' => 'test1',
'country' => 'abc'
)
1 => array(
'name' => 'test2',
'country' => 'xyz'
)
)
1 => array(
'name' => 'test3',
'country' => 'pqr'
)
);
How can I make all arrays as parallel arrays. So that all sub arrays are parallel to each other without using any loop.
Like this
$arr = array(
0 => array(
'name' => 'test1',
'country' => 'abc'
)
1 => array(
'name' => 'test2',
'country' => 'xyz'
)
2 => array(
'name' => 'test3',
'country' => 'pqr'
)
);
Any help is much appreciated. !
A dynamic version of Nigel's code would be to loop the array and merge each subarray.
$new = [];
foreach($arr as $subarr){
$new = array_merge($new, $subarr);
}
var_dump($new);
https://3v4l.org/np2ZD
You could simply merge the arrays...
$out = array_merge($arr[0], [$arr[1]]);
print_r($out);
Which gives...
Array
(
[0] => Array
(
[name] => test1
[country] => abc
)
[1] => Array
(
[name] => test2
[country] => xyz
)
[2] => Array
(
[name] => test3
[country] => pqr
)
)

PHP Array of arrays of arrays

I am trying to search this array by the value of ['field'] and then return the value of ['value'] associated with that field in the array.
For example, I want to say "Tell me the value associated with theThirdField".
I've tried many, many permutations of something like the following:
$myVariable = $Array['result']['totalrows'][0]['rownum'][0]['field'];
To further clarify, I will never know which order / sub-array my search field is located in, I only know the string value associated with ['field'].
How would I accomplish this?
Array
(
[result] => Array
(
[totalrows] => 1
[rows] => Array
(
[0] => Array
(
[rownum] => 1
[values] => Array
(
[0] => Array
(
[field] => testMeOnce
[value] => 436586498
)
[1] => Array
(
[field] => testMeTwice
[value] => 327698034
)
[2] => Array
(
[field] => theThirdField
[value] => 108760374
)
[3] => Array
(
[field] => theFourthField
[value] => 2458505
)
[4] => Array
(
[field] => fifthField
[value] => -0.0201
)
)
)
)
)
)
Did you expect something like that?
$needle = 'theThirdField'; // searched field name
$valuesArray = $Array['result']['rows'][0]['values']; //now you have clearer array
array_walk($valuesArray, function($element, $key) use ($needle) {
if ($element['field'] == $needle) {
echo $element['value'];
}
});
I would do something like this, assuming you want to search only in the $myVariable dimension :
$myVariable = $Array['result']['rows'][0]['values'];
foreach ($myVariable as $key => $value) {
if( $value['field'] === 'theThirdField' ) {
echo $value['value'];
break;
}
}
when I ran your code, I got some syntax errors. I have changed your Array to this (changed syntax only):
$a = Array
(
'result' =>
[
'totalrows' => 1,
'rows' =>
[
0 =>
[
'rownum' => 1,
'values' =>
[
0 =>
[
'field' => 'testMeOnce',
'value' => 436586498
],
1 =>
[
'field' => 'testMeTwice',
'value' => 327698034
],
2 =>
[
'field' => 'theThirdField',
'value' => 108760374
],
3 =>
[
'field' => 'theFourthField',
'value' => 2458505
],
4 =>
[
'field' => 'fifthField',
'value' => -0.0201
]
]
]
]
]
);
now you can get the value like this:
print($a['result']['rows'][0]['values'][2]['value']); // --> 108760374
I hope that this is what you are looking for!
Thanks everyone. I used a mix of your suggestions and ended up doing the following:
$valuesArray = $Array['result']['rows'][0]['values'];
foreach ($valuesArray as $value) {
$fieldName = $value['field'];
$$fieldName = $value['value'];
}
Since I know the names of all the fields I want, but not the order, this allowed me to capture all of the values of each field with the name of the field becoming the variable name.

Categories