i have string like this
$string = 'root.1.child1.2.nextnode.3.anothernode.4.var';
exploded by "." and created array like this
$arr = array('root','1','child1','2','nextnode','3','anothernode','3','var');
how i can convert this array to something like this ?
it should be dynamically convert because in some cases nodes in string are in a number different with the sample .
["root"]=>
array(1) {
[1]=>
array(1) {
["child1"]=>
array(1) {
[2]=>
array(1) {
["nextnode"]=>
array(1) {
[3]=>
array(1) {
["anothernode"]=>
array(1) {
[3]=>
array(1) {
[var]=>
NULL
}
}
}
}
}
}
}
}
An example using recursive function.
$array = ['root', '1', 'child1', '2', 'nextnode', '3', 'anothernode', '3', 'var'];
function getNestedArray(array $arr, int $idx = 0) {
if ($idx + 1 <= count($arr)) {
return [$arr[$idx] => getNestedArray($arr, $idx + 1)];
}
return null;
}
$output = getNestedArray($array);
var_dump($output);
This can be quit easily achieved by referencing the output and looping over the exploded array:
$output = [];
$reference = &$output;
foreach ($arr as $el) {
if (is_numeric($el)) {
$el = (int)$el;
}
$reference = [];
$reference[$el] = null;
$reference = &$reference[$el];
}
This also checks whether the element is a number and casts it to an integer if it is. The $output variable will contain the final array.
You can use recursive function
to do though
$flatArray = array('root','1','child1','2','nextnode','3','anothernode','3','var'); // your array
function createNestedArray($flatArray)
{
if( sizeof($flatArray) == 1 ) {
return [ $flatArray[0] => null ]; // for the case that paramter has one member we need to return [ somename => null ]
}
$nestedArray[ $flatArray[0] ] = createNestedArray(array_slice($flatArray, 1)); // otherwise we need to call createNestedArray with rest of array
return $nestedArray;
}
$nestedArray = createNestedArray($flatArray); // the result
Related
Is it possible to search an array for a given value and return all the indexes at which the value was found? So for this array:
["Red","Green","Red","Blue"]
I need
[0,2]
with regard to a search for "Red". Searching for "Yellow" in this case would return an empty array.
You can use like this:
$array = ["Red","Green","Red","Blue"];
$output = array_keys($array, "Red");
The $output will be [0,2]
I think this should work:
$input = ["Red","Green","Red","Blue"];
$x = "Red";
$keys = array_keys(array_filter($input, function ($v) use ($x) { return $v === $x;}));
You can iterate the array with foreach:
foreach($input_arr as $key => $value){
if($value == 'Red'){
needed_key_arr[] = $key;
}
}
Also, if you can have an array of values you what to search use:
$lookup_arr = ['Red', 'Green'];
foreach($input_arr as $key => $value){
if(in_array($value, $lookup_arr)){
needed_key_arr[] = $key;
}
}
$arr = ["Red","Green","Red","Blue"];
$valueToSearchFor = ["Red"];
$keys = array_keys(array_filter($arr, function ($val1) use ($valueToSearchFor) { // filter the first array
return array_filter($valueToSearchFor, function ($val) use ($val1) { // use the first array's value
return $val == $val1; // compare them and then return them
});
}));
var_dump($keys) // array(2) { [0]=> int(0) [1]=> int(2) }
First we filter the array then take the values from the first filter to another filter then we match the arrays and we return them. This works for multiple values too.
$arr = ["Red","Green","Red","Blue"];
$valueToSearchFor = ["Red", "Blue"];
$keys = array_keys(array_filter($arr, function ($val1) use ($valueToSearchFor) {
return array_filter($valueToSearchFor, function ($val) use ($val1) {
return $val == $val1;
});
}));
var_dump($keys) // array(3) { [0]=> int(0) [1]=> int(2) [2]=> int(3) }
I have a simple way to detect references in an array (For debugging purposes)
First I clone the array with array_values and then I alter the clone and look for changes in the original. If it's changed that element is a reference.
Short example:
<?php
$a = [
'a' => 'b',
2 => 3,
];
$b = ['wow'];
$a['ref'] = &$b;
function getrefs($array) {
$marker = uniqid();
$copy = array_values($array);
$i = 0;
$return = [];
foreach ($array as $key => &$val) {
$stash = $val;
$copy[$i] = $marker;
if ($val === $marker) {
$val = $stash;
$return[] = $key;
}
$i++;
}
return $return;
}
var_dump($a);
var_dump(getrefs($a));
The problem is that when I try to use this on $GLOBALS it's not working, and I can't figure out why. Everything in $GLOBALS should be a reference by all rights.
Is $GLOBALS just so strange that it's the only array where array_values won't correctly copy references?
It's a possibility that you're not accounting for recursion. The built-in PHP function:
var_dump($GLOBALS);
Will have the following output
array(7) {
["_GET"]=>
array(0) {
}
["_POST"]=>
array(0) {
}
["_COOKIE"]=>
array(1) {
["PHPSESSID"]=>
string(26) "od602et6qcfj6pa3pkjtl8go57"
}
["_FILES"]=>
array(0) {
}
["GLOBALS"]=>
*RECURSION*
["_SESSION"]=>
&array(0) {
}
}
Here is my code.
I am trying to get inspect link for steam item. I have tried to use preg_replace but no luck either.
$API_link = sprintf("http://steamcommunity.com/id/*steamid*/inventory/json/730/2?trading=1");
$json = file_get_contents($API_link);
$json_output = json_decode($json);
$result = $json_output;
$link = array();
$id = array();
foreach($result->rgDescriptions AS $item){
$empty = array();
$newstring = $item->actions[0]->link;
if($newstring == NULL){
continue;
} else {
$empty['link'] = $newstring;
array_push($link, $empty);
}
}
foreach($result->rgInventory AS $inventory){
$empty = array();
if($inventory->instanceid == 0){
continue;
} else {
$empty['id'] = $inventory->id;
array_push($id, $empty);
}
}
$array = array_merge($id, $link);
foreach($array AS $final){
$assetid = "%assetid%";
echo str_replace($assetid, $final['id'], $final['link']);
}
}
But its not working. Please see if you can help.
As I can see you have array of arrays:
// bracket squares equivalent of array() keyword PHP >=v5.4
// here is
// $link = array(['link'=>'url'],['link'=>'url'])
// $id = array(['id'=>'id'],['id'=>'id'])
// result will be:
// array(['link']=>'url'],['link'=>'url'],['id'=>'id'],['id'=>'id'])
$array = array_merge($id, $link);
foreach($array AS $final){
// here is the first $final
// array('link'=>'url')
$assetid = "%assetid%";
// but here is we try to get
// 'id' and 'link'
echo str_replace($assetid, $final['id'], $final['link']);
}
I think it's some kind of mistake.
Ok, some test script:
<?php
$a = array( array('link'=>'hello1'), array('link'=>'hello2'));
$b = array( array('id'=>'id0'), array('id'=>'id1'));
$c = array_merge($a, $b);
var_dump($c);
result:
array(4) {
[0] =>
array(1) {
'link' =>
string(6) "hello1"
}
[1] =>
array(1) {
'link' =>
string(6) "hello2"
}
[2] =>
array(1) {
'id' =>
string(3) "id0"
}
[3] =>
array(1) {
'id' =>
string(3) "id1"
}
}
array_merge doesn't mix your associative arrays between them nether all nor particular item (I hope I explain it correct)
of course
foreach ($c as $item) {
var_dump($item);
}
will enumerate all the items one by one
array(1) {
'link' =>
string(6) "hello1"
}
array(1) {
'link' =>
string(6) "hello2"
}
array(1) {
'id' =>
string(3) "id0"
}
array(1) {
'id' =>
string(3) "id1"
}
and there is no array that has both of them (link and id) in the item
This script can't associate link and id properly, cause some of links can be skipped by continue, some of id also can be skipped. And it will be just a random list of available information. You can stuck in the next situation:
- $links has first 10 links
- $id has 3,4,5,7,9,11
It's just a list. Even if you have only this pure info (no other details), you can't properly associate it between of them by using shown source.
Here is minimum 1 simple solutions:
don't skip, don't merge, just add an empty array, and your final loop will be like this:
$assetid = "%assetid%";
for ($link as $key=>$final) {
if (count($final) && count($id[$key])) {
echo str_replace($assetid, $id[$key]['id'], $final['link']);
} else {
// some of needed arguments absent
}
}
Description not enough. Maybe try dump some variables?
foreach($array AS $final){
$assetid = "%assetid%";
//Check what is in $final
var_dump($final);
echo str_replace($assetid, $final['id'], $final['link']);
}
I have an array of JSON objects that look like this:
{"id":1,"place":2,"pic_name":"aaa.jpg"}
My PHP file receives a simple array like:
["4","3","1","2","5"]
These numbers correspond to the place value in my JSON object. Now I need to compare the place of each element in the secont array with the value of ID in the JSON object and if the match I have to replace the value of PLACE with the element from the array.
I am having problems doing the comparison. Any guidelines? What I come up with:
foreach($ids as $index=>$id) { //the array
$id = (int) $id;
foreach ($obj as $key=>$value) { //the JSON objects
foreach ($value as $k=>$v){
if ($id != '' && array_search($index, array_keys($ids)) == $value[$k]['id']) {
$value[$k]['place'] = $id;
file_put_contents($file, json_encode($ids));
} else { print "nope";}
} } }
That will be:
$array = [
'{"id":1,"place":2,"pic_name":"aaa.jpg"}',
'{"id":2,"place":5,"pic_name":"aab.jpg"}',
'{"id":3,"place":1,"pic_name":"aba.jpg"}',
'{"id":4,"place":3,"pic_name":"baa.jpg"}',
'{"id":5,"place":4,"pic_name":"abb.jpg"}'
];
$places = ["4","3","1","2","5"];
$array = array_map(function($item)
{
return json_decode($item, 1);
}, $array);
foreach($array as $i=>$jsonData)
{
if(false!==($place=array_search($jsonData['id'], $places)))
{
$array[$i]['place'] = $place+1;
}
}
$array = array_map('json_encode', $array);
//var_dump($array);
-with output like:
array(5) {
[0]=>
string(39) "{"id":1,"place":3,"pic_name":"aaa.jpg"}"
[1]=>
string(39) "{"id":2,"place":4,"pic_name":"aab.jpg"}"
[2]=>
string(39) "{"id":3,"place":2,"pic_name":"aba.jpg"}"
[3]=>
string(39) "{"id":4,"place":1,"pic_name":"baa.jpg"}"
[4]=>
string(39) "{"id":5,"place":5,"pic_name":"abb.jpg"}"
}
I want to create a file tree, and for this purpose I need to convert an array of files and directories to a multidimensional file tree array. For example:
array
(
'file.txt',
'dir1/',
'dir1/dir2/',
'dir1/dir2/dir3/',
'dir1/file.txt',
)
to
array
(
'file.txt',
'dir1' =>
array
(
'dir2' =>
array
(
'dir3' =>
array(),
),
'file.txt',
)
)
I've tried several functions to accomplish this, but non of them worked. The problem I've encountered for example that there is no easy way to convert an array ('test','test','test'),'test' to $array['test']['test']['test'] = 'test'.
Here's a shorter recursive one:
function dir_tree($dir) {
$files = array_map('basename', glob("$dir/*"));
foreach($files as $file) {
if(is_dir("$dir/$file")) {
$return[$file] = dir_tree("$dir/$file");
} else {
$return[] = $file;
}
}
return $return;
}
Take a look to my post here.
The answer is: strtok will save you.
<?php
$input = [
'/RootFolder/Folder1/File1.doc',
'/RootFolder/Folder1/SubFolder1/File1.txt',
'/RootFolder/Folder1/SubFolder1/File2.txt',
'/RootFolder/Folder2/SubFolder1/File2.txt',
'/RootFolder/Folder2/SubFolder1/SubSubFolder1/File4.doc',
];
function parseInput($input) {
$result = array();
foreach ($input AS $path) {
$prev = &$result;
$s = strtok($path, '/');
while (($next = strtok('/')) !== false) {
if (!isset($prev[$s])) {
$prev[$s] = array();
}
$prev = &$prev[$s];
$s = $next;
}
$prev[] = $s;
unset($prev);
}
return $result;
}
var_dump(parseInput($input));
Output :
array(1) {
["RootFolder"]=>
array(2) {
["Folder1"]=>
array(2) {
[0]=>
string(9) "File1.doc"
["SubFolder1"]=>
array(2) {
[0]=>
string(9) "File1.txt"
[1]=>
string(9) "File2.txt"
}
}
["Folder2"]=>
array(1) {
["SubFolder1"]=>
array(2) {
[0]=>
string(9) "File2.txt"
["SubSubFolder1"]=>
array(1) {
[0]=>
string(9) "File4.doc"
}
}
}
}
}
I have PHP snippet for that:
<?php
function wps_glob($dir) {
foreach (glob($dir . '/*') as $f) {
if(is_dir($f)) {
$r[] = array(basename($f) => wps_glob($f));
}
else {
$r[] = basename($f);
}
}
return $r;
}
function wps_files($path) {
$wpsdir = Array(
'root' => $path,
'struktur' => wps_glob($path)
);
return $wpsdir;
}
?>
example usage here