$variable = '
persons.0.name = "peter"
persons.0.lastname = "griffin"
persons.1.name = "homer"
persons.1.lastname = "simpsons"';
I want to generate from that $variable an array that looks like this
array(2) {
[0]=>
array(2) {
["name"]=>
string(5) "peter"
["lastname"]=>
string(7) "griffin"
}
[1]=>
array(2) {
["name"]=>
string(5) "homer"
["lastname"]=>
string(7) "simpson"
}
}
so far this is what I have so far.
$temp = explode('\r\n', $persons);
$sets = [];
foreach ($temp as $value)
{
$array = explode('=', $value);
if ($array[0] != '')
{
$array[1] = trim($array[1], '"');
$sets[$array[0]] = $array[1];
$output = $sets;
}
}
that generates "persons.1.name" as a key and "peter" as a value
I´m not sure how to generate arrays based on "." thank you.
I tried with parse_ini_string() but basically is doing the same thing.
You can use array_reduce and explode
$variable = '
persons.0.name = "peter"
persons.0.lastname = "griffin"
persons.1.name = "homer"
persons.1.lastname = "simpsons"';
$temp = explode(PHP_EOL, $variable);
$result = array_reduce($temp, function($c, $v){
$v = explode( "=", $v );
if ( trim( $v[0] ) !== "" ) {
$k = explode( ".", $v[0] );
$c[ $k[ 1 ] ][ $k[ 2 ] ] = $v[1];
}
return $c;
}, array());
echo "<pre>";
print_r( $result );
echo "</pre>";
This will result to:
Array
(
[0] => Array
(
[name ] => "peter"
[lastname ] => "griffin"
)
[1] => Array
(
[name ] => "homer"
[lastname ] => "simpsons"
)
)
Doc: http://php.net/manual/en/function.array-reduce.php
UPDATE: If you want to set depth, you can
$variable = '
persons.0.name = "peter"
persons.0.lastname = "griffin"
persons.1.name = "homer"
persons.1.lastname = "simpsons"
data = "foo"
url = so.com?var=true
';
$temp = explode(PHP_EOL, $variable);
$result = array_reduce($temp, function($c, $v){
$v = explode( "=", $v, 2 );
if ( trim( $v[0] ) !== "" ) {
$k = explode( ".", $v[0] );
$data = $v[1];
foreach (array_reverse($k) as $key) {
$data = array( trim( $key ) => $data);
}
$c = array_replace_recursive( $c, $data );
}
return $c;
}, array());
echo "<pre>";
print_r( $result );
echo "</pre>";
This will result to:
Array
(
[persons] => Array
(
[0] => Array
(
[name] => "peter"
[lastname] => "griffin"
)
[1] => Array
(
[name] => "homer"
[lastname] => "simpsons"
)
)
[data] => "foo"
[url] => so.com?var=true
)
PHP's ini parsing is limited and wouldn't parse that even if it was persons[0][name] = "peter".
Taken from my answer here How to write getter/setter to access multi-level array by key names?, first just explode on = to get the key path and value, and then explode on . for the keys and build the array:
$lines = explode("\n", $variable); //get lines
list($path, $value) = explode('=', $lines); //get . delimited path to build keys and value
$path = explode('.', $path); //explode path to get individual key names
$array = array();
$temp = &$array;
foreach($path as $key) {
$temp =& $temp[trim($key)];
}
$temp = trim($value, '"');
Also trims spaces and ".
Because each line contains the full address to and data for the array, we can create everything with a loop instead of recursion.
// Create variable for final result
$output=[];
// Loop over input lines, and let PHP figure out the key/val
foreach (parse_ini_string($variable) AS $key=>$val) {
$stack = explode('.', $key);
$pos = &$output;
// Loop through elements of key, create when necessary
foreach ($stack AS $elem) {
if (!isset($pos[$elem]))
$pos[$elem] = [];
$pos = &$pos[$elem];
}
// Whole key stack created, drop in value
$pos = $val;
}
// The final output
var_dump($output);
Output:
array(1) {
["persons"]=>
array(2) {
[0]=>
array(2) {
["name"]=>
string(5) "peter"
["lastname"]=>
string(7) "griffin"
}
[1]=>
array(2) {
["name"]=>
string(5) "homer"
["lastname"]=>
&string(8) "simpsons"
}
}
}
Related
Hi I am working on very complex array operations.
I have $temp variable which stores pipe separated string like Height=10|Width=20
I have used explode function to convert into array and get specific output.
Below code i have try :
$product_attributes = explode("|",$temp)
//below output i get after the explode.
$product_attributes
Array(
[0]=>Height=10
[1]=>width=20
)
But i want to parse this array to separate one.
My expected output :
Array (
[0]=>Array(
[0] => Height
[1] => 10
)
[1]=>Array(
[0]=>Width
[1]=>20
)
)
Which function i need to used to get the desire output ?
Before downvoting let me know if i have made any mistake
You could try the below code. I've tested this and it outputs the result you've shown in your post.
$temp = 'Height=10|Width=20';
$product_attributes = explode('|', $temp);
$product_attributes2 = array();
foreach ($product_attributes as $attribute) {
$product_attributes2[] = explode('=', $attribute);
}
print_r($product_attributes2);
Try Below code
<?php
$temp = "Height=10|Width=20";
$product_attributes = explode("|", $temp);
foreach ($product_attributes as $k => $v) {
$product_attributes[$k] = explode('=', $v);
}
echo '<pre>';
print_r($product_attributes);
?>
check running answer here
Process your result by this:
$f = function($value) { return explode('=', $value); }
$result = array_map($f, $product_attributes);
One more option is to split the values in to one array and then build them from there.
$str = "Height=10|Width=20";
$arr = preg_split("/\||=/", $str);
$arr2= array();
$j=0;
for($i=0;$i<count($arr);$i++){
$arr2[$j][]= $arr[$i];
$arr2[$j][]= $arr[$i+1];
$i++;
$j++;
}
var_dump($arr2);
The output will be:
$arr = array(4){
0 => Height
1 => 10
2 => Width
3 => 20
}
$arr2 = array(2) {
[0]=>
array(2) {
[0]=>
string(6) "Height"
[1]=>
string(2) "10"
}
[1]=>
array(2) {
[0]=>
string(5) "Width"
[1]=>
string(2) "20"
}
}
Lets say i have this array:
$first = ['hi', 'by', 'nice']
I am going to assign another array to this array items.In fact doing a foreach loop and due to situation assign a new array to desired array item.
Now i want turn it to this:
$second = ['hi', 'by' => ['really' => 'yes'], 'nice']
How can i do it programmatically?
Try this
$first = ['hi', 'by', 'nice'];
foreach( $first as $key => $value )
{
$second[] = $value;
if( $value == 'by' )
{
$second[ $value ][] = array( 'really' => 'yes' );
}
}
var_dump( $second );
Output:
array(4) {
[0]=>
string(2) "hi"
[1]=>
string(2) "by"
["by"]=>
array(1) {
[0]=>
array(1) {
["really"]=>
string(3) "yes"
}
}
[2]=>
string(4) "nice"
}
This is very important, if index by is known than you can use this index for checking and store values into a new array otherwise this will failed.
Here is basic example:
<?php
$first = ['hi', 'by', 'nice'];
$newArr = array();
foreach ($first as $key => $value) {
if($value == 'by'){
$newArr[$value] = array('really'=>'yes');
}
else{
$newArr[] = $value;
}
}
echo "<pre>";
print_r($newArr);
?>
Result:
Array
(
[0] => hi
[by] => Array
(
[really] => yes
)
[1] => nice
)
If I understand your requirement, actually there are many way exists to do this. This is mine,
<?php
$first = ['hi', 'by', 'nice'];
foreach($first as $k=>$v){
if($v !='by'){
$second[] = $v;
}else{
$second[$v] = ['really'=>'yes'];
}
}
print_r($second);
?>
Try this :
$second = $first;
$tofind = 'by';
$key = array_search($tofind, $second);
unset($second[$key]);
$second[$tofind] = array( 'really' => 'yes' );
My "main" array looks like this - var_dump($main)
[zlec_addresoperator] => and
[filtervalue0] => Test
[filtercondition0] => CONTAINS
[filteroperator0] => 1
[filterdatafield0] => zlec_addres
[zlec_nroperator] => and
[filtervalue1] => SecondVal
[filtercondition1] => CONTAINS
[filteroperator1] => 1
[filterdatafield1] => zlec_nr
I want to build a new array as
array( filterdatafield0 = > filtervalue0 , filterdatafield1 = > filtervalue1)
etc
First of all I decided to filter out what I wan't with the following codes. Creating new arrays to keep the data I wan't, so $arraykeys will contain the filterdatafield.{1,2} values. In this case it will be zlec_addres and zlec_nr.
The second $arrayvalue will keep the filtervalue.{1,2} which is the value for the filter.
$newarray = array();
$arraykeys = array();
$arrayvalue = array();
foreach($_GET as $key => $value):
if(preg_match("/^filterdatafield.{1,2}$/",$key)>0) {
// $key is matched by the regex
$arrayvalue[] = $value;
}
if(preg_match("/^filtervalue.{1,2}$/",$key)>0) {
// $key is matched by the regex
$arraykeys[] = $key;
}
endforeach;
foreach($arraykeys as $a){
$newarray[$a] = $arrayvalue;
}
So the desired output would be
array(
zlec_addres => 'Test', zlec_nr = 'SecondVal'
)
Now it is
array(12) {
["filtervalue0"]=>
array(12) {
[0]=>
string(11) "zlec_addres"
[1]=>
string(7) "zlec_nr"
...
}
["filtervalue1"]=>
array(12) {
[0]=>
string(11) "zlec_addres"
[1]=>
string(7) "zlec_nr"
...
}
$newarray = array();
$arraykeys = array();
$arrayvalue = array();
foreach($_GET as $key => $value){
if(preg_match("/^filterdatafield.{1,2}$/",$key)>0) {
// $key is matched by the regex
$arraykeys[] = $value;
}
if(preg_match("/^filtervalue.{1,2}$/",$key)>0) {
// $key is matched by the regex
$arrayvalues[] = $value;
}
}
$newArray = array_combine($arraykeys, $arrayvalues);
This should work for you:
Just grab your keys which you want with preg_grep() and then array_combine() both arrays together.
<?php
$arr = [
"zlec_addresoperator" => "and",
"filtervalue0" => "Test",
"filtercondition0" => "CONTAINS",
"filteroperator0" => "1",
"filterdatafield0" => "zlec_addres",
"zlec_nroperator" => "and",
"filtervalue1" => "SecondVal",
"filtercondition1" => "CONTAINS",
"filteroperator1" => "1",
"filterdatafield1" => "zlec_nr",
];
$newArray = array_combine(
preg_grep("/^filterdatafield\d+$/", array_keys($arr)),
preg_grep("/^filtervalue\d+$/", array_keys($arr))
);
print_r($newArray);
?>
output:
Array
(
[filterdatafield0] => filtervalue0
[filterdatafield1] => filtervalue1
)
in PHP, is it possible to cut the |xyz part away from the key names?
The array looks like this:
array(30) {
["1970-01-01|802"]=>
array(4) {
["id"]=>
string(3) "176"
["datum"]=>
string(10) "1970-01-01"
["title"]=>
string(8) "Vorschau"
["alias"]=>
string(16) "vorschau-v15-176"
}
["1970-01-01|842"]=>
array(4) {
["id"]=>
string(3) "176"
["datum"]=>
string(10) "1970-01-01"
["title"]=>
string(8) "Vorschau"
["alias"]=>
string(16) "vorschau-v15-176"
} ...
Thank you for your help,
toni
For example, you might use this:
$newArray = array();
foreach( $oldArray as $key => $value ) {
$newArray[ substr( $key, 0, 10 ) ] = $value;
}
Or modify the array in-place:
foreach( $someArray as $key => $value ) {
unset( $someArray[ $key ] );
$someArray[ substr( $key, 0, 10 ) ] = $value;
}
Both solutions will loose value
Since the keys in your source array are
1970-01-01|802
1970-01-01|842
the output array will loose some array values: Both keys get mapped to a single destination key:
1970-01-01
Keeping all values
If you don't want to loose values, try this:
$newArray = array();
foreach( $someArray as $key => $value ) {
$newKey = substr( $key, 0, 10 );
if ( ! isset( $newArray[ $newKey ] )) {
$newArray[ $newKey ] = array();
}
$newArray[ $newKey ][] = $value;
}
Result array structure of this solution:
array(
'1970-01-01' =>
array(
0 => ...,
1 => ...
),
'1970-01-02' =>
array(
0 => ...,
1 => ...,
2 => ...
),
...
);
Kind of.. just create a new array with the trimmed key, then set the old aray equal to the new one.
$newArray = array();
foreach ($arrayList as $key => $data) {
$keyParts = explode("|", $key);
$newArray[$keyParts[0]] = $data;
}
$arrayList = $newArray;
It could be possible but in this case you would end up with 2 of the same array keys.
["1970-01-01"] and ["1970-01-01"]
The xyz behind it is required in this case.
You can do it with preg_replace:
$keys = preg_replace('/(.+)\|\d+/', '$1', array_keys($arr));
$arr = array_combine($keys, $arr);
I need to reconstruct an array. Here is the original array:
array(8) {
[0] => array(1)
{
["L_TRANSACTIONID0"] => string(17) "62M97388AY676841D"
}
[1] => array(1)
{
["L_TRANSACTIONID1"] => string(17) "9FF44950UY3240528"
}
[2] => array(1)
{
["L_STATUS0"] => string(9) "Completed"
}
[3] => array(1)
{
["L_STATUS1"] => string(9) "Completed"
}
}
I would like to reconstruct it to be as such:
array(2) {
[0] => array(2)
{
["L_TRANSACTIONID0"] => string(17) "62M97388AY676841D"
["L_STATUS0"] => string(9) "Completed"
}
[1] => array(1)
{
["L_TRANSACTIONID1"] => string(17) "9FF44950UY3240528"
["L_STATUS1"] => string(9) "Completed"
}
}
Notice that the KEYS both match with the numeric representation... Is this at all possible?
edit:
here is my code I am using:
foreach($comparison as $key => $val) {
$findme1 = 'L_TRANSACTID'.$i++;
$findme2 = 'L_STATUS'.$c++;
$arrDisable = array($findme1,$findme2);
if( in_array($key, $arrDisable ) ) {
unset( $comparison[ $key ][$val]);
}
if( in_array($key, $arrDisable) ) {
unset( $comparison[ $key ][$val]);
}
}
Try this
$labels = array('L_TRANSACTIONID', 'L_STATUS');
$res = array();
foreach($arr as $val) {
$key = str_replace($labels, '', key($val));
$res[$key] = isset($res[$key]) ? array_merge($res[$key], $val) : $val;
}
print_r($res);
http://codepad.org/MwqTPqtA
If you are certain the the vector cointains pairs L_TRANSACTIONIDn / L_STATUSn keys,that is to say, for each transactionID, there is a corresponding status, what you can do, is to get the number of id/status records (which should equal the length of the initial array, divided by two), and compose the resultin keys, by increasing the current element count.
Could look something like this:
$numItems = sizeof($myInitialArray) / 2;
$newArray = array();
for($i = 0; $i < $numItems; $i++)
{
$itemID = $i * 2; // since we're getting id/status pairs, we're using a step equal to 2
$newArray[] = array(
("L_TRANSACTIONID" . $i) => $myInitialArray[$itemID], // this is the id value
("L_STATUS" . $i) => $myInitialArray[$itemID + 1] // this is the status for that id
);
}
Hope this helps. Have a great day!