I've an array of folders/paths:
$arr = Array
(
0 => Array
(
'name' => 'aaa'
),
1 => Array
(
'name' => 'aaa\bbb'
),
2 => Array
(
'name' => 'aaa\bbb\ccc'
),
3 => Array
(
'name' => 'ddd'
)
);
I'd like to transform it to multidimensional (tree-like) array (keeping the structure: index/key & value/name):
aaa
bbb
ccc
ddd
Any suggests?
Try:
$arr = array(
array('name' => 'aaa'),
array('name' => 'aaa\bbb'),
array('name' => 'aaa\bbb\ccc'),
array('name' => 'ddd'),
array('name' => 'ddd\zzz'),
array('name' => 'zzz'),
array('name' => 'ddd\zzz\fff'),
);
$new = array();
$helper = array();
foreach ($arr as $i => $entry) {
$parent =& $new;
/**
* One could use:
* explode(DIRECTORY_SEPARATOR, $entry['name'])
*
* instead of '\\' if you're dealing with file-structures
*/
foreach ($path = explode('\\', $entry['name']) as $ii => $element) {
$subPath = implode('.', array_slice($path, 0, $ii + 1));
if (isset($helper[$subPath])) {
$parent =& $helper[$subPath];
continue;
}
$parent[$i] = array('name' => $element);
$helper[$subPath] =& $parent[$i];
}
}
print_r($new);
Output:
Array
(
[0] => Array
(
[name] => aaa
[1] => Array
(
[name] => bbb
[2] => Array
(
[name] => ccc
)
)
)
[3] => Array
(
[name] => ddd
[4] => Array
(
[name] => zzz
[6] => Array
(
[name] => fff
)
)
)
[5] => Array
(
[name] => zzz
)
)
$newarr=array();
foreach ($arr as $element) {
$currentroot=$newarr;
$pieces=explode('\\', $element);
for ($x=0; $x<=count($pieces); x++) {
$currentroot[$pieces[$x]]=array();
$currentroot=$currentroot[$pieces[$x]];
}
}
Untested but should get you started. You need to add a condition to check if it is the last piece, and make it a string value instead of an array.
Well, had to do it in two functions, but here goes:
// Directory Array to Hierarchy
function _DAtoH($path, $result = null)
{
if (empty($path)) return array();
if (is_null($result)) $result = array();
$path = explode(DIRECTORY_SEPARATOR, $path);
$curr = array_shift($path);
if (!isset($result[$curr]))
$result[$curr] = array();
$result[$curr] = _DAtoH(implode(DIRECTORY_SEPARATOR, $path), $result[$curr]);
return $result;
}
function DAtoH($arr)
{
$result = array();
foreach ($arr as $a)
$result = _DAtoH($a,$result);
return $result;
}
Passing the bottom function (the _DAtoH is just a recursive helper) the array you specified in your original question (var_dump(DAtoH($arr));), you should receive:
array(2) {
["aaa"]=>
array(2) {
["bbb"]=>
array(1) {
["ccc"]=>
array(0) {
}
}
["fff"]=>
array(0) {
}
}
["ddd"]=>
array(1) {
["eee"]=>
array(0) {
}
}
}
(Note: I added some folder paths just to test it out, thus the fff, eee, etc.)
For the new requirements:
$arr = array(
array('name' => 'aaa'),
array('name' => 'aaa\bbb'),
array('name' => 'aaa\bbb\ccc'),
array('name' => 'ddd'),
);
function traverse(array $array) {
$mark=array_shift($array);
return array($mark => $array ? traverse($array) : array() );
}
$out = array();
foreach($arr as $path)
{
($add=traverse(explode('\\',$path['name'])))
&& $out[key($add)]=current($add)
;
}
Output:
array(2) {
["aaa"]=>
array(1) {
["bbb"]=>
array(1) {
["ccc"]=>
array(0) {
}
}
}
["ddd"]=>
array(0) {
}
}
Old Question:
The old question had these reqs:
$arr = array(
0 => 'aaa',
1 => 'aaa\bbb',
2 => 'aaa\bbb\ccc',
);
function traverse(array $array) {
$mark=array_shift($array);
return $array ? array($mark => traverse($array)) : $mark;
}
$out = array();
foreach($arr as $path)
{
is_array($add=traverse(explode('\\',$path)))
&& $out[key($add)]=current($add)
;
}
Tested, giving this output:
array(1) {
["aaa"]=>
array(1) {
["bbb"]=>
string(3) "ccc"
}
}
Related
I am trying to update each language as a multidimensional array to another multidimensional array but it seems to be only saving the last key e.g.(lang_3) but not lang_1 & lang_2. Cracking my head to figure this out. Hope someone can point out my faults. ($country_specs = list of language, $get_code = country code)
$awards = array(
'award_year' => sanitize_array_text_field($_POST['award_year']),
'award_title_user' => sanitize_array_text_field($_POST['award_title_user']),
'award_description_user' => sanitize_array_text_field($_POST['award_description_user'])
);
foreach ($country_specs as $specs => $value) {
if ($value[0] == $get_code ) {
foreach ($value['lang'] as $lang_key => $lang) {
$awards_title = 'award_title_'.$lang_key;
$awards_description = 'award_description_'.$lang_key;
$awards_lang = array(
$awards_title => sanitize_array_text_field($_POST[$awards_title]),
$awards_description => sanitize_array_text_field($_POST[$awards_description])
);
update_user_meta($user_id, 'awards', array_merge($awards,$awards_lang));
}
}
}
Current code output example:
Array (
[award_year] => Array (
[0] => 1999-01
[1] => 2010-02 )
[award_title_user] => Array (
[0] => 2
[1] => tt )
[award_description_user] => Array (
[0] => 2
[1] => ddd )
[award_title_lang3] => Array (
[0] => 2CC
[1] => zz )
[award_description_lang3] => Array (
[0] => 2CCCCCCC
[1] => dzz ) )
Working code as follows.
$awards = array(
'award_year' => sanitize_array_text_field($_POST['award_year']),
'award_title_user' => sanitize_array_text_field($_POST['award_title_user']),
'award_description_user' => sanitize_array_text_field($_POST['award_description_user'])
);
$awards_new_lang = array();
foreach ($country_specs as $specs => $value) {
if ($value[0] == $get_code ) {
foreach ($value['lang'] as $lang_key => $lang) {
$awards_title = 'award_title_'.$lang_key;
$awards_description = 'award_description_'.$lang_key;
$awards_new_lang[$awards_title] = sanitize_array_text_field($_POST[$awards_title]);
$awards_new_lang[$awards_description] = sanitize_array_text_field($_POST[$awards_description]);
}
}
}
$array_merge_new = array_merge($awards, $awards_new_lang);
update_user_meta($user_id, 'awards', $array_merge_new);
I created a new array ($awards_new_lang) and did an array merge with the old array, thus combining both of the arrays together.
Try this code, it outputs as expected, I tried the mimic the variables structures
<?php
$awards = array(
'award_year' => '1999',
'award_title_user' => '2',
'award_description_user' => '2CCCCCCC'
);
$value = array();
$value['lang'] = array(1, 2, 3);
foreach ($value['lang'] as $lang_key) {
$awards_title = 'award_title_'.$lang_key;
$awards_description = 'award_description_'.$lang_key;
$awards_lang = array(
$awards_title => "$lang_key title",
$awards_description => "$lang_key desc"
);
//array merge returns an array, we save the changes here to use them later when the loops are through
$awards = array_merge($awards,$awards_lang);
}
echo '<pre>';
//Final updated version of the array
var_dump($awards);
echo '</pre>';
?>
Outputs:
array(9) {
["award_year"]=>
string(4) "1999"
["award_title_user"]=>
string(1) "2"
["award_description_user"]=>
string(8) "2CCCCCCC"
["award_title_1"]=>
string(7) "1 title"
["award_description_1"]=>
string(6) "1 desc"
["award_title_2"]=>
string(7) "2 title"
["award_description_2"]=>
string(6) "2 desc"
["award_title_3"]=>
string(7) "3 title"
["award_description_3"]=>
string(6) "3 desc"
}
I have an array which contains list of pagrank values. Consider below array:
Array
(
[0] => stdClass Object
(
[pagerank] => 3
)
[1] => stdClass Object
(
[pagerank] => 1
)
[2] => stdClass Object
(
[pagerank] => R
)
[3] => stdClass Object
(
[pagerank] => 2
)
[4] => stdClass Object
(
[pagerank] => 7
)
)
I want to shift/move page rank with 'R' like:
[2] => stdClass Object
(
[pagerank] => R
)
to the end of array and it should be on last index of array?
Edit: The array key is unknown.
If the index is unknown:
foreach($array as $key => $val) {
if($val->pagerank == 'R') {
$item = $array[$key];
unset($array[$key]);
array_push($array, $item);
break;
}
}
If you don't want to modify the array while it is being iterated over just find the index then make the modifications.
$foundIndex = false;
foreach($array as $key => $val) {
if($val->pagerank == 'R') {
$foundIndex = $key;
break;
}
}
if($foundIndex !== false) {
$item = $array[$foundIndex];
unset($array[$foundIndex]);
array_push($array, $item);
}
$item = $array[2];
unset($array[2]);
array_push($array, $item);
Something like this?
$var = array(
'name' => 'thename',
'title' => 'thetitle',
'media' => 'themedia'
);
// Remove first element (the name)
$name = array_shift($var);
// Add it on to the end
$var['name'] = $name;
var_dump($var);
/*
array(3) {
["title"]=>
string(8) "thetitle"
["media"]=>
string(8) "themedia"
["name"]=>
string(7) "thename"
}
*/
Ref: http://forums.phpfreaks.com/topic/177878-move-array-index-to-end/
$item=null;
foreach ($array['pagerank'] as $key => $value)
{
if( $value=="R")
{
$item = $array[$key];
unset($array[$key]);
break;
}
}
if($item !=null)
array_push($array, $item);
Try this :
$arr = array(array("pagerank" => 3),
array("pagerank" => 1),
array("pagerank" => 'R'),
array("pagerank" => 4),
array("pagerank" => 7),
array("pagerank" => 5),
array("pagerank" => 2)
);
foreach($arr as $key=>$ar){
if($ar["pagerank"] == "R"){
$unset = $key;
break;
}
}
$val = $arr[$unset];
unset($arr[$unset]);
$arr[] = $val;
print_r($arr);
If what you're looking for is specifically the value of r, you can use array_search
array_search returns the key if an item exists in the array, otherwise returns false.
$needle = "R";
if($key = array_search($needle, $pageRankArray)) {
unset($pageRankArray[$key]); // Delete an item from the array
array_push($pageRankArray, $needle); // inserts element at the end of the array
}
If you want to place R as the last value and keeping your keys, you could do this:
$arr = array(
(object)array('pagerank' => 1),
(object)array('pagerank' => 'R'),
(object)array('pagerank' => 2),
);
// Store in temp var.
$tmp_arr = $arr;
// Sort temp array to put 'R' in top.
asort($tmp_arr);
// Reset to be able to find the first key in the sorted array.
reset($tmp_arr);
// Get key from first value in array.
$key = key($tmp_arr);
// Store value from first key.
$item = $tmp_arr[$key];
// Unset key from original array.
unset($arr[$key]);
// Insert as last value in original array using original key.
$arr[$key] = $item;
// Print result.
var_dump($arr);
This will give you:
array(3) {
[0]=>
object(stdClass)#1 (1) {
["pagerank"]=>
int(1)
}
[2]=>
object(stdClass)#3 (1) {
["pagerank"]=>
int(2)
}
[1]=>
object(stdClass)#2 (1) {
["pagerank"]=>
string(1) "R"
}
}
See: http://codepad.org/gPhrktuJ
foreach ($arr as $key => $value){
if ($value->pagerank == 'R'){
$arr[] = $value;
unset($arr[$key]);
break;
}
}
$arr = array_values($arr);
If you have more than one object with a 'R' value:
$current_array = $sorted_array = Array(
...
);
foreach($current_array as $current_key => $element){
if($element->pagerank == 'R'){
unset($sorted_array[$current_key]);
$sorted_array[] = $element;
}
}
unset($current_array);
Just use array_filter.
Taking $arr as input array:
$arr=Array
(
(Object) ['pagerank' => 3],
(Object) ['pagerank' => 1],
(Object) ['pagerank' => "R"],
(Object) ['pagerank' => 2],
(Object) ['pagerank' => 7],
);
$result=array_filter($arr,function($item){return $item->pagerank!="R";})+$arr;
var_dump($arr,$result);
The result will be:
array (size=5)
0 =>
object(stdClass)[1]
public 'pagerank' => int 3
1 =>
object(stdClass)[2]
public 'pagerank' => int 1
2 =>
object(stdClass)[3]
public 'pagerank' => string 'R' (length=1)
3 =>
object(stdClass)[4]
public 'pagerank' => int 2
4 =>
object(stdClass)[5]
public 'pagerank' => int 7
array (size=5)
0 =>
object(stdClass)[1]
public 'pagerank' => int 3
1 =>
object(stdClass)[2]
public 'pagerank' => int 1
3 =>
object(stdClass)[4]
public 'pagerank' => int 2
4 =>
object(stdClass)[5]
public 'pagerank' => int 7
2 =>
object(stdClass)[3]
public 'pagerank' => string 'R' (length=1)
I have an array called $result, which is shown below:
array(1)
{ ["response"]=> array(3)
{ [0]=> array(1)
{ ["list"]=> array(2)
{ ["category"]=> string(6) "(noun)"
["synonyms"]=> string(27) "chelonian|chelonian reptile" }
}
[1]=> array(1)
{ ["list"]=> array(2)
{ ["category"]=> string(6) "(verb)"
["synonyms"]=> string(57) "capsize|turn turtle|overturn|turn over|tip over|tump over" }
}
[2]=> array(1)
{ ["list"]=> array(2)
{ ["category"]=> string(6) "(verb)"
["synonyms"]=> string(29) "hunt|run|hunt down|track down" }
}
}
}
I am trying to access the ["synonyms"] element, and split each word and store it in its own string, or perhaps an array of all the words. You can see the words are separated by the | symbol.
I have tried the following code, which did not work (results did not display, so explode did not work) :
$i=0;
foreach ($result["response"] as $value)
{
foreach ($value["list"]["synonyms"] as $temp)
{
$alternative[$i] = explode ("|", $temp);
$i++;
}
}
//OUTPUT THE RESULTS
$j=0;
foreach ($alternative as $echoalternative)
{
echo $j.": ".$echoalternative;
$j++;
}
Any ideas? Thanks guys.
You're trying to iterate over the string in your interior foreach. Try
foreach ($result["response"] as $value)
{
$alternative[$i] = explode ("|", $value["list"]["synonyms"]);
$i++;
}
To create an array of single dimensional arrays (given that you have three groups in your original array), you can do the following:
$out = array();
foreach ($arr['response'] as $key => $value){
$syns = explode('|', $value['list']['synonyms']);
foreach ($syns as $key2 => $value2){
$out[$key][] = $value2;
}
}
To access the single dimensional array for the group of synonyms with index 0, just do the following:
var_dump($out[0]);
Array(
[0] => chelonian
[1] => chelonian reptile
)
If you just want to display the synonyms, you can do something like this:
foreach ($arr['response'] as $key => $value){
$syns = explode('|', $value['list']['synonyms']);
foreach ($syns as $key2 => $value2){
echo $value2.', ';
}
echo "<br />";
}
Output:
chelonian, chelonian reptile,
capsize, turn turtle, overturn, turn over, tip over, tump over,
hunt, run, hunt down, track down,
However, if you want to include that in the original array, you can do this:
array_walk_recursive($arr, function (&$e, $k){
if (preg_match('#[\w\|]+#', $e)){
$e = explode('|', $e);
}
});
var_dump($arr);
Output:
Array(
[response] => Array
[0] => Array(
[list] => Array(
[category] => Array(
[0] => (noun)
)
[synonyms] => Array(
[0] => chelonian
[1] => chelonian reptile
)
)
)
[1] => Array(
[list] => Array(
[category] => Array(
[0] => (verb)
)
[synonyms] => Array(
[0] => capsize
[1] => turn turtle
[2] => overturn
[3] => turn over
[4] => tip over
[5] => tump over
)
)
)
[2] => Array(
[list] => Array(
[category] => Array(
[0] => (verb)
)
[synonyms] => Array(
[0] => hunt
[1] => run
[2] => hunt down
[3] => track down
)
)
)
)
)
The following refactored code should resolve the issue
$i=0;
foreach ($result["response"] as $value)
{
// print_r($value);
$temp = $value["list"]["synonyms"];
// echo $temp;
// foreach ($value["list"]["synonyms"] as $temp)
// {
$alternative[$i] = explode ("|", $temp);
$i++;
// }
}
//OUTPUT THE RESULTS
$j=0;
foreach ($alternative as $echoalternative)
{
print_r($echoalternative);
echo $j.": ".$echoalternative;
$j++;
}
My array is given below. Which contains more than one arrays.
Array
(
[0] => Array
(
[user_id] => 1
[name] => name1
)
[1] => Array
(
[user_id] => 2
[name] => name2
)
[2] => Array
(
[user_id] => 2
[name] => name2
)
[3] => Array
(
[user_id] => 3
[name] => name3
)
)<br/>
I need arrays which has more than one occurence.In this case
Array
(
[user_id] => 2
[name] => name2
)
Try this.
function get_multi_occur($my_array)
{
foreach ($my_array as $id => $a) {
$key = $a[user_id] . $a[name];
if ($s[$key]['cnt'] == 0) {
$s[$key]['cnt'] = 1;
$s[$key]['id'] = $id;
} else {
$s[$key]['cnt']++;
}
}
foreach ($s as $r) {
if ($r['cnt'] >= 2) {
$ret[] = $my_array[$r[id]];
}
}
return $ret;
}
foreach ($array as $key_1=>$sub_array_1)
{
foreach ($array as $key_2=>$sub_array_2)
{
if ($sub_array_1 == $sub_array_2 &&
$key_1 != $key_2)//prevent to compare same sub arrays
print_r($sub_array_1);
}
}
something like this
You can try
$array = Array(
"0" => Array("user_id" => 1,"name" => "name1"),
"1" => Array("user_id" => 2,"name" => "name2"),
"2" => Array("user_id" => 2,"name" => "name2"),
"3" => Array("user_id" => 3,"name" => "name3"));
$d = $s = array();
array_map(function ($v) use(&$d, &$s) {
array_key_exists($v['user_id'], $s) && ! array_key_exists($v['user_id'], $d) ? $d[$v['user_id']] = $v : $s[$v['user_id']] = $v;
}, $array);
var_dump($d);
Output
array
2 =>
array
'user_id' => int 2
'name' => string 'name2' (length=5)
Create a new array that will store data that have same values.
Try this code :
$array_existing = array();
$ctr = 0;
foreach ($first_array as $key => $first) :
foreach ($second_array as $keytwo => $second) :
if ($first['user_id'] == $second['user_id'] && $first['name'] == $second['name']) {
$array_existing[$ctr]['user_id'] = $first['user_id'];
$array_existing[$ctr]['name'] = $first['name'];
$array_existing[$ctr]['first_index'] = $key;
$array_existing[$ctr]['second_index'] = $keytwo;
$ctr++;
}
endforeach;
endforeach;
var_dump($array_existing);
Hi it is any way to connect to records where value is the same?
like
[12]=> Array (
[ID] => 127078
[row1] =>
[post] => N16 7UJ
)
[13]=> Array (
[ID] => 127078
[row1] => something
[post] =>
)
and make like that
[12]=> Array (
[ID] => 127078
[row1] => something
[post] => N16 7UJ
)
Here take this function
<?php
$array = array(
12 => array (
"ID" => '127078',
"row1" => '',
"post" => 'N16 7UJ',
),
13 => array (
"ID" => '127078',
"row1" => 'something',
"post" => '',
)
);
function mergedup($array,$matcher){
if(!function_exists('remove_element')){
function remove_element($arr,$element){
$ret_arr = array();
foreach($arr as $val){
if($val !== $element){
array_push($ret_arr,$val);
}
}
return $ret_arr;
}
}
$array = remove_element($array,array());
$return_array = array();
while(isset($array[0])){
$temp = $array[0];
$array = remove_element($array,$temp);
$array_temp = array();
foreach($array as $vals){
if($temp[$matcher]==$vals[$matcher]){
array_push($array_temp,$vals);
foreach($temp as $key => $val){
if(empty($temp[$key])){
$temp[$key] = $vals[$key];
}
}
}
}
foreach($array_temp as $vals){
$array = remove_element($array,$vals);
}
array_push($return_array,$temp);
}
return $return_array;
}
var_dump(mergedup($array,"ID"));
?>
Tested and working
You have so many option such as array_replace
array_merge
foreach
while
Iterator
But i prefer array_replace because you can easily select which array is replacing which
Values
$array[12] = array("ID"=>127078,"row1"=>"","post"=>"N16 7UJ");
$array[13] = array("ID"=>127078,"row1"=>"something","post"=>"");
var_dump($array[12]);
Example array_replace ( http://www.php.net/manual/en/function.array-replace.php )
$array[13] = array_filter($array[13]); //Filter Replacement
$array[12]= array_replace($array[12],$array[13]);
Example array_merge ( http://php.net/manual/en/function.array-merge.php )
//$array[12] = array_filter($array[12]); //Optinal
$array[13] = array_filter($array[13]); //Filter Spaces
$array[12]= array_merge($array[12],$array[13]);
var_dump($array[12]);
Output
array
'ID' => int 127078
'row1' => string 'something' (length=9)
'post' => string 'N16 7UJ' (length=7)