converting config ini like string dot separated value to actual array keys - php

got a multidimensional array and a string in a config and i need to transform it as an array key without the use of eval. Real world use of this problems is that i got a big document from mongodb that is transformed into multi dimensional array. However i need to define specific array nodes from a config file.
the idea is to create a config file as representation of the array key's hierarchy
on the config.ini the values below are some example.
colorattribute = attribute.color
wholesaleprice = prices.wholesale
Example Response from mongoDb
<?php
$products = array(
'product_name' => 'iTouch',
'brand_name' => 'Apple',
'attributes' => array ( 'color' => 'black',
'size' => '5 in'
),
'prices' => array(
'wholesale' => 135,
'retail' => 200,
),
);

function recurseKeys(array $keys,array $array){
$key = array_shift($keys);
if(!isset($array[$key])) return null;
return empty($keys) ?
$array[$key]:
recurseKeys($keys,$array[$key];
}
var_dump(recurseKeys(explode('.',$testConfig),$products);

Related

How to expand a dot notation array into a full multi-dimensional array

In my Laravel project, I have a dot notation array which I need to convert to a multi-dimensional array.
The array is something like this:
$dotNotationArray = ['cart.item1.id' => 15421a4,
'cart.item1.price' => '145',
'cart.item2.id' => 14521a1,
'cart.item2.price' => '1245'];
How can I expand it to an array like:
'cart' => [
'item1' => [
'id' => '15421a4',
'price' => 145
],
'item2' => [
'id' => '14521a1',
'price' => 1245,
]
]
How can I do this?
In Laravel 6+ you can use Arr::set() for this:
The Arr::set method sets a value within a deeply nested array using "dot" notation:
use Illuminate\Support\Arr;
$multiDimensionalArray = [];
foreach ($dotNotationArray as $key => $value) {
Arr::set($multiDimensionalArray , $key, $value);
}
dump($multiDimensionalArray);
If you are using Laravel 5.x you can use the array_set() instead, which is functionally identical.
Explanation:
Arr::set() sets value for a key in dot notation format to a specified key and outputs an array like ['products' => ['desk' => ['price' => 200]]]. so you can loop over your array keys to get a multidimensional array.

How to extract specific array keys and values to another array?

I have an array of arrays like so:
array( array(), array(), array(), array() );
the arrays inside the main array contain 4 keys and their values. The keys are the same among all arrays like this:
array( 'id' => 'post_1',
'desc' => 'Description 1',
'type' => 'type1',
'title' => 'Title'
);
array( 'id' => 'post_2',
'desc' => 'Description 2',
'type' => 'type2',
'title' => 'Title'
);
So I want to create another array and extract the id and type values and put them in a new array like this:
array( 'post_1' => 'type1', 'post_2' => 'type2'); // and so on
The keys in this array will be the value of id key old arrays and their value will be the value of the type key.
So is it possible to achieve this? I tried searching php.net Array Functions but I don't know which function to use?
PHP 5.5 introduced an array function that does exactly what you want.
I'm answering this in hopes that it may help someone in future with this question.
The function that does this is array_column.
To get what you wanted you would write:
array_column($oldArray, 'type', 'id');
To use it on lower versions of PHP either use the accepted answer or take a look at how this function was implemented in PHP and use this library: https://github.com/ramsey/array_column
Just use a good ol' loop:
$newArray = array();
foreach ($oldArray as $entry) {
$newArray[$entry['id']] = $entry['type'];
}

Storing the full location of an element in a multidimensional array for reuse

This question is based on my other question here about a suitable array processing algorithm.
In my case, I want to flatten a multidimensional array, but I need to store the full key to that element for reuse later.
For example :
array(
0 => array(
'label' => 'Item1',
'link' => 'http://google.com',
'children' => null
)
1 => array(
'label' => 'Item2',
'link' => 'http://google.com',
'children' => array( 3 => array(
'label' => 'SubmenuItem1',
'link' => 'http://www.yahoo.com',
'children' => null
)
)
)
2 => array(
'label' => 'Item3',
'link' => 'http://google.com',
'children' => null
)
)
Should be flattened into something like the following table
Key Link
===================================
[0] http://google.com
[1] http://google.com
[2] http://google.com
[1][3] http://yahoo.com
The problem is that I while I can easily store the location of an element in a multidimensional array, I am finding it to be quite hard to retrieve that element later. For example, if I store my key as $key = "[1][3]", I can not access it using $myarray[$key]. Is there anyway to do this?
Solution using recursion:
//Array parts should be an array containing the keys, for example, to address
//SubmenuItem1, I had 1.3 when the array was flattened. This was then exploded() to the array [1, 3]
$this->recurseIntoArray($myArray, $arrayParts);
private function recurseIntoArray(&$array, $arrayParts){
$current = $arrayParts[0];
$array[$current]['blah'] = 'blah'; //If you want to update everyone in the chain on the way down, do it here
array_shift($arrayParts);
if (!empty($arrayParts)){
$this->recurseIntoArray($array[$current]['children'], $arrayParts);
}else{
//If you want to update only the last one in the chain, do it here.
}
}

Can I store an array within a multidimensional array? (PHP)

It is possible to put an array into a multi dim array? I have a list of user settings that I want to return in a JSON array and also have another array stored in that JSON array...what is the best way to do that if it isn't possible?
A multi dimension is already an array inside an array. So there's nothing stopping you from putting another array in there. Sort of like dreams within dreams :P
Just use associative arrays if you want to give your array meaning
array(
'SETTINGS' => array(
'arr1' => array( 0, 1),
'arr2' => array( 0, 1)
),
'DATA' => array(
'arr1' => array( 0, 1),
'arr2' => array( 0, 1)
)
)
EDIT
To answer your comment, $output_files[$file_id]['shared_with'] = $shared_info; translates to (your comment had an extra ] which I removed)
$shared_info = array(1, 2, 3);
$file_id = 3;
$output_files = array(
'3' => array(
'shared_with' => array() //this is where $shared_info will get assigned
)
);
//you don't actually have to declare it an empty array. I just did it to demonstrate.
$output_files[$file_id]['shared_with'] = $shared_info; // now that empty array is replaced.
any array key can have an array value in php, as well as in json.
php:
'key' => array(...)
json:
"key" : [...]
note: php doesn't support multidimensional arrays as in C or C++. it's just an array element containing another array.

Need help about array

What do
$categories[$id] = array('name' => $name, 'children' => array());
and
$categories[$parentId]['children'][] = array('id' => $id, 'name' => $name);
mean?
Thanks a lot.
How should i format the output so i can learn the results that was returned?
You can format your code into tables by looping on the array using for or foreach. Read the docs for each if you don't have a grasp on looping.
2.What does
$categories[$id] = array('name' => $name, 'children' => array());
and
$categories[$parentId]['children'][] = array('id' => $id, 'name' => $name);
The first line assigns an associative array to another element of the $categories array. For instance if you wanted the name of the category with ID of 6 it would look like this:
$categories[6]['name']
The second line does something similar, except when you are working with an array in PHP, you can use the [] operator to automatically add another element to the array with the next available index.
What is the uses of .= ?
This is the concatenation assignment operator. The following two statements are equal:
$string1 .= $string2
$string1 = $string1 . $string2
These all have to do with nesting arrays.
first example:
$categories[$id] = array('name' => $name, 'children' => array());
$categories is an array, and you are setting the key id to contain another array, which contains name and another array. you could accomplish something similar with this:
$categories = array(
$id => array(
'name' => $name,
'children' => array()
)
)
The second one is setting the children array from the first example. when you have arrays inside of arrays, you can use multiple indexes. It is then setting an ID and Name in that array. here is a another way to look at example #2:
$categories = array(
$parentID => array(
'children' => array(
'id' = $id,
'name' => $name
)
)
)
note: my two ways of rewriting are functionally identical to what you posted, I'm just hoping this makes it easier to visualize what's going on.

Categories