function groupByOwners(array $files) : array { return []; }
$files = array("Input.txt" => "Randy","Code.py" => "Stan","Output.txt" =>"Randy");
Print_r(groupByOwners($files);
My expected output is:
[Randy => [Input.txt, Output.txt] , Stan => [Code.py]]
You just need to iterate over your array, pushing each filename to a new array indexed by the names:
function groupByOwners(array $files) : array {
$output = array();
foreach ($files as $file => $name) {
$output[$name][] = $file;
}
return $output;
}
$files = array("Input.txt" => "Randy","Code.py" => "Stan","Output.txt" =>"Randy");
print_r(groupByOwners($files));
Output:
Array
(
[Randy] => Array
(
[0] => Input.txt
[1] => Output.txt
)
[Stan] => Array
(
[0] => Code.py
)
)
Demo on 3v4l.org
Related
I have dynamic multidimensional array like this :
Array
(
[0] => index.php
[src] => Array
(
[src2] => Array
(
[src3] => Array
(
[0] => test_src3.php
)
[0] => Array
(
[0] => test_src2.php
)
)
[0] => test_src.php
)
[src_test] => Array
(
[New Folder] => Array
(
)
[src_test2] => Array
(
[New Folder] => Array
(
)
[src_test3] => Array
(
)
)
)
[1] => test.php
)
The number of dimensions might be change based on sub directories that found in a folder path inputted by user (this program is used by a person in their local).
How could i fetch those array elements so that the result would be like this :
array(
[0] => src/src2/src3
[1] => src_test/New Folder
[2] => src_test/src_test2/New Folder/
[3] => src_test/src_test2/src_test3
)
By the way i have a function to achieve this :
function getKeyPaths(array $tree, $glue = '/'){
$paths = array();
foreach ($tree as $key => &$mixed) {
if (is_array($mixed)) {
$results = getKeyPaths($mixed, $glue);
foreach ($results as $k => &$v) {
$paths[$key . $glue . $k] = $v;
}
unset($results);
} else {
$paths[$key] = $mixed;
}
}
return $paths;
}
the above function does not result like what i expected:
Array
(
[0] => index.php
[src/src2/src3/0] => test_src3.php
[src/src2/0/0] => test_src2.php
[src/0] => test_src.php
)
How do i achieve this ?
One approach :
function getKeyPaths(array $tree, $glue = '/', $return_array = true){
$paths = "";
foreach ($tree as $key => &$mixed) {
$path = $key . $glue;
if (is_array($mixed) && !is_int($key) ) {
$paths .= $path . getKeyPaths( $mixed, $glue, false);
if ($return_array) {
$paths .= "|";
}
}
}
if ($return_array) {
return explode("|", trim($paths, "|"));
}
return $paths;
}
In a foreach loop i would like to compare [name] value beetween different arrays but they have not the same levels.
Array(
[array1] => Array
(
[0] => WP_Term Object
(
[name] => Plafond
)
)
[array2] => WP_Term Object
(
[name] => Chaudière
)
[array3] => Array
(
[0] => WP_Term Object
(
[name] => Pla
)
[1] => WP_Term Object
(
[name] => Toc
)
)
)
I don't know how could i get the [name] in the same loop whereas levels are different.
I have tried to make :
foreach( $fields as $name => $value )
{
echo $value->name; }
Should i add another loop in the first loop ?
thanks
So your data looks like this:
$json = '{"array1":[{"name":"Plafond"}],"array2":{"name":"Chaudière"},"array3":[{"name":"Pla"},{"name":"Toc"}]}';
$array = json_decode($json);
If you don't know how deep it will go, a simple recursive function should work. Perhaps something like this:
function get_name($o, &$output) {
if (is_array($o)) {
foreach($o as $v) {
get_name($v, $output);
}
} elseif (property_exists($o, "name")) {
$output[] = $o->name;
}
}
$output = [];
foreach ($array as $v) {
get_name($v, $output);
}
If you data is going to look like the sample you provided (i.e. it will always be first or second level) then you don't need to worry about recursion.
$output = [];
foreach ($array as $k=>$v) {
if (is_array($v)) {
foreach ($v as $k2=>$v2) {
$output[] = $v2->name;
}
} else {
$output[] = $v->name;
}
}
Either way, your output values are all in the $output array:
print_r($output);
Output:
Array
(
[0] => Plafond
[1] => Chaudière
[2] => Pla
[3] => Toc
)
You can use array_map, array_key_exists to retrive the name index from the array
$jsonFormat = '{"array1":[{"name":"Plafond"}],"array2":{"name":"Chaudière"},"array3":[{"name":"Pla"},{"name":"Toc"}]}';
$jsonArray = json_decode($jsonFormat,true);
$res = [];
array_map(function($v) use (&$res){
if(array_key_exists('name', $v)){
$res[] = $v['name'];
}else{
foreach($v as $_key => $_value){
$res[] = $_value['name'];
}
}
}, $jsonArray);
echo '<pre>';
print_r($res);
Result:-
Array
(
[0] => Plafond
[1] => Chaudière
[2] => Pla
[3] => Toc
)
You can use $res to compare the names.
I have a following piece of code:-
$returnArr = $this->master_model->fetch_all_data($data, $selectString,$limit, $offset);
foreach($returnArr as $row)
{
if (array_key_exists($data.'_image', $row))
{
$img = base_url()."uploads/$data/". $row[$data.'_image'];
$row[$data.'_image'] = $img;
}
}
print_r($returnArr);
The $return is in the following format:
Array ( [0] =>
Array ( [sticker_image] => post_1462515402.jpg
[sticker_code] => :* )
[1] => Array ( [sticker_image] => post_1462515510.jpg
[sticker_code] => ^=^ )
[2] => Array ( [sticker_image] => post_1462515532.jpg
[sticker_code] => >_<* )
[3] => Array ( [sticker_image] => post_1462515539.jpg
[sticker_code] => :(( ) )
Now, in the following line of code, I am changing [sticker_image] to a link:
if (array_key_exists($data.'_image', $row))
{
$img = base_url()."uploads/$data/". $row[$data.'_image'];
$row[$data.'_image'] = $img;
}
Still, the changes doesn't take place. It's still coming as
[sticker_image] => post_1462515402.jpg
What am I doing wrong?
$row[$data.'_image'] = $img; will change only local copy of array element.
To change actual array element you must loop with reference:
$returnArr = ['a' => 'b'];
foreach ($returnArr as &$row) {
$row = 'cc';
}
var_dump($returnArr); // ['a' => 'cc'];
In the db:
{"49530fe2e872288d92042b3059f31566":{"filename":"49530fe2e872288d92042b3059f31566.jpg"},"4b7dc54328383c294ceb884e9691838c":{"filename":"4b7dc54328383c294ceb884e9691838c.jpg"}}
After using print:
Array (
[49530fe2e872288d92042b3059f31566] => Array (
[filename] => 49530fe2e872288d92042b3059f31566.jpg
)
[4b7dc54328383c294ceb884e9691838c] => Array (
[filename] => 4b7dc54328383c294ceb884e9691838c.jpg
)
)
How can I access filename?
Use foreach loop over the array to get filename.
<?php
$j = '{"49530fe2e872288d92042b3059f31566":{"filename":"49530fe2e872288d92042b3059f31566.jpg"},"4b7dc54328383c294ceb884e9691838c":{"filename":"4b7dc54328383c294ceb884e9691838c.jpg"}}';
$a = json_decode($j, TRUE);
if (! empty($a)) {
foreach ($a as $e) {
echo '<pre>';print_r($e['filename']);echo '</pre>';
}
}
?>
Use foreach loop if you are not aware of keys of array.
$arr = array (
'49530fe2e872288d92042b3059f31566' => array (
'filename' => '49530fe2e872288d92042b3059f31566.jpg'
),
'4b7dc54328383c294ceb884e9691838c' => array (
'filename' => '4b7dc54328383c294ceb884e9691838c.jpg'
)
); //To obtain this array from json , do **$arr = json_decode($json, true);**
foreach($arr as $val){
$filename = $val['filename']; //There you go
}
I have the following array:
Array
(
[0] => INBOX.Trash
[1] => INBOX.Sent
[2] => INBOX.Drafts
[3] => INBOX.Test.sub folder
[4] => INBOX.Test.sub folder.test 2
)
How can I convert this array to a multidimensional array like this:
Array
(
[Inbox] => Array
(
[Trash] => Array
(
)
[Sent] => Array
(
)
[Drafts] => Array
(
)
[Test] => Array
(
[sub folder] => Array
(
[test 2] => Array
(
)
)
)
)
)
Try this.
<?php
$test = Array
(
0 => 'INBOX.Trash',
1 => 'INBOX.Sent',
2 => 'INBOX.Drafts',
3 => 'INBOX.Test.sub folder',
4 => 'INBOX.Test.sub folder.test 2',
);
$output = array();
foreach($test as $element){
assignArrayByPath($output, $element);
}
//print_r($output);
debug($output);
function assignArrayByPath(&$arr, $path) {
$keys = explode('.', $path);
while ($key = array_shift($keys)) {
$arr = &$arr[$key];
}
}
function debug($arr){
echo "<pre>";
print_r($arr);
echo "</pre>";
}
I was very interested in this as was having immense difficulty trying to do this. After looking at (and going through) Jon's solution I have come up with this:
$array = array();
function parse_folder(&$array, $folder)
{
// split the folder name by . into an array
$path = explode('.', $folder);
// set the pointer to the root of the array
$root = &$array;
// loop through the path parts until all parts have been removed (via array_shift below)
while (count($path) > 1) {
// extract and remove the first part of the path
$branch = array_shift($path);
// if the current path hasn't been created yet..
if (!isset($root[$branch])) {
// create it
$root[$branch] = array();
}
// set the root to the current part of the path so we can append the next part directly
$root = &$root[$branch];
}
// set the value of the path to an empty array as per OP request
$root[$path[0]] = array();
}
foreach ($folders as $folder) {
// loop through each folder and send it to the parse_folder() function
parse_folder($array, $folder);
}
print_r($array);