public function include_header( $h, $h_data ) {
// Require header file
if (isset($h) && !empty($h)) {
$this->header_file = 'includes/header/'.$h;
} else { return false; }
// Pass optional array of parameters
if (isset($h_data) && is_array($h_data) && !empty($h_data)) {
// Loop through array & assign keys to appropriate class members
foreach($h_data as $key => $val) {
if ($key == 'doctype') { $this->doctype = $val; }
if ($key == 'title') { $this->title = $val; }
if ($key == 'meta') {
// The meta key is should be an array in h_data
// so, we'll have to loop through the meta array
// in order to parse the individual meta elements.
foreach($key as $meta_key => $meta_val) {
$this->error = $meta_key;
}
}
}
} else { return false; }
}
I'm trying to loop through a multidimensional array, where I have the following variable...
$h_data['meta']['individual_element']
I'm trying to loop through the 'meta', so I can access each individual value, but I'm having trouble. Please help! Thanks in advance!
foreach($key as $meta_key => $meta_val) {
$this->error = $meta_key;
}
... should be
foreach($val as $meta_key => $meta_val) {
$this->error = $meta_key;
}
if ($key == 'meta') {
// The meta key is should be an array in h_data
// so, we'll have to loop through the meta array
// in order to parse the individual meta elements.
foreach($val as $meta_key => $meta_val) { //val not key
$this->error = $meta_key;
}
Related
I building a translation form that is build using a array filled with the translation keys, to keys are however often duplicated. As the form is builded in group i want to move the duplicates to the $translatables['global']
Note that what you're seeing in the image below is already placed in $translatables['modules']['Module_{{ModuleName}}']
As you can see in the image below, some fields are duplicates. those needs to be moved. The duplicates can be placed accross multiple elements.
I edit for the duplicate message: It ain't, its a question to move those values not to filter them (and keep 1 remaining), they need to be placed under a global section.
I solved it myself
class Tools_Array
{
public static function find_duplicates_recursive(&$array, $remove = false)
{
$duplicates = array();
$valueCounts = array_count_values(self::array_values_recursive($array));
foreach ($valueCounts as $key => $value) {
if ($value > 1)
{
$duplicates[] = $key;
}
}
if ($remove) {
foreach ($duplicates as $duplicate)
{
$array = self::remove_values_recursive($array, $duplicate);
}
}
return $duplicates;
}
public static function array_values_recursive($array)
{
$arr2 = array();
foreach ($array as $key => $value)
{
if(is_array($value))
{
$arr2 = array_merge(array_values_recursive($value), $arr2);
}else{
$arr2[] = $value;
}
}
return $arr2;
}
public static function remove_values_recursive($array, $needle)
{
foreach ($array as $key => $value)
{
if(is_array($value))
{
$array[$key] = self::remove_values_recursive($value, $needle);
}else{
if ($value == $needle)
{
unset($array[$key]);
}
}
}
return $array;
}
}
Then i can filter it with:
$duplicates = Tools_Array::find_duplicates_recursive($translatables, true);
$translatables['globaal'] = array_merge($translatables['globaal'], $duplicates);
I would to create a recursive function in order to retrieve data from an array and to organize then.
However I have some difficulties to create the right logic. The principle must be apply to any sub level until it ends or nothing is found.
I want to prevent this kind of code by repeating a foreach inside a foreach...:
$cats = get_categories($args);
$categories = array();
foreach($cats as $cat){
$parent = $cat->category_parent;
if ($parent) {
$categories['child'][$parent][$cat->cat_ID] = $cat->name;
} else {
$categories['parent'][$cat->cat_ID] = $cat->name;
}
}
}
if (isset($categories['parent']) && !empty($categories['parent'])) {
foreach($categories['parent'] as $id => $cat){
$new_cats[$id]['title'] = $cat;
if (isset($categories['child'][$id])) {
foreach($categories['child'][$id] as $child_id => $child_cat){
$new_cats[$child_id]['title'] = $child_cat;
$new_cats[$child_id]['parent_id'] = $id;
if (isset($categories['child'][$child_id])) {
foreach($categories['child'][$child_id] as $sub_child_id => $sub_child_cat){
$new_cats[$sub_child_id]['title'] = $sub_child_cat;
$new_cats[$sub_child_id]['parent_id'] = $child_id;
}
}
}
}
}
}
}
May be this code help you to get idea for formatting your desired array format.
<?php
// Main function
function BuildArr($arr)
{
$formattedArr = array();
if(!empty($arr))
{
foreach($arr as $val)
{
if($val['has_children'])
{
$returnArr = SubBuildArr($val['children']); // call recursive function
if(!empty($rs))
{
$formattedArr[] = $returnArr;
}
}
else
{
$formattedArr[] = $val;
}
}
}
return $formattedArr;
}
// Recursive Function( Build child )
function SubBuildArr($arr)
{
$sub_fortmattedArr = array();
if(!empty($arr))
{
foreach($arr as $val)
{
if($val['has_children'])
{
$response = SubBuildArr($val['children']); // call recursive
if(!empty($response))
{
$sub_fortmattedArr[] = $response;
}
}
else
{
$sub_fortmattedArr[] = $arr;
}
}
return $sub_fortmattedArr;
}
}
?>
I use this code for my previous project for generating categories that upto n-th level
I have a json feed that is more or less a list of objects
each has it's own id and idParent. objects that have idParent of null are the base parent elements. What I'm trying to achieve is to make a proper multidimensional array like a tree view. Keep in mind that children can have children too.
{
"obj1":{
"idParent":null,
"id":"parent1"
},
"obj2":{
"idParent":null,
"id":"parent2"
},
"obj3":{
"idParent":null,
"id":"parent3"
},
"obj4":{
"idParent":null,
"id":"parent4"
},
"obj5":{
"idParent":null,
"id":"parent5"
},
"obj6":{
"idParent":"parent1",
"id":"layer1-1"
},
"obj7":{
"idParent":"parent1",
"id":"layer1-2"
},
"obj8":{
"idParent":"parent2",
"id":"layer1-3"
},
"obj9":{
"idParent":"parent4",
"id":"layer1-4"
},
"obj10":{
"idParent":"parent3",
"id":"layer1-5"
},
"obj11":{
"idParent":"layer1-1",
"id":"layer2-1"
},
"obj12":{
"idParent":"parent5",
"id":"layer2-2"
},
"obj13":{
"idParent":"layer1-4",
"id":"layer2-3"
},
"obj14":{
"idParent":"layer1-5",
"id":"layer2-4"
},
"obj15":{
"idParent":"layer1-5",
"id":"layer2-5"
}
}
I've managed to filter out the root parents but after that I fail very bad
The first function does filter out the root parent nodes with idParent of null.
function decodeData($data) {
global $out;
foreach ($data as $key => $obj) {
if (is_array($obj)) {
foreach ($obj as $prop => $value) {
if ($prop == 'idParent') {
if($value == null) {
array_push($out, $obj);
unset($data[$key]);
}
}
}
}
}
if (count($data) > 0) {
decodeData($data);
} else {
echo json_encode(array('length'=>count($data)));
}
}
And this is what I'm experimenting on with no result
function decodeData($arrays) {
global $out;
foreach ($arrays as $array_name => $arr) {
foreach ($arr as $arr_prop => $arr_val) {
if ($arr_prop == 'idParent' && $arr_val == null) { // we found root parents
array_push($out, $arr);
unset($arrays[$array_name]); //remove array from the list
} else { // check if idParent is inside out
foreach ($out as $out_arr_name => $out_arr) { // iterate through out arrays
foreach ($out_arr as $out_arr_prop => $out_prop_val) { //
if ($out_arr_prop == 'id' && $arr_prop == 'idParent' && $out_arr_val == $arr_val) {
array_push($out_arr['children'], $obj);
unset($arrays[$array_name]);
}
}
}
}
}
}
if (count($arrays) > 0) {
decodeData($arrays);
} else {
echo json_encode(array('length'=>count($arrays)));
}
}
If anyone could provide some help I would really appreciate it.
I couldn't figure out what output do you want, so I just made a simple tree structure:
$data = json_decode( $your_json_string );
// Store each element in a lookup table indexed by element id
// 0th pass: put a fake root element there
$by_id = array(
'*' => new stdclass
);
// First pass: put each element into there
foreach( $data as $o ) $by_id[ $o->id ] = $o;
// Second pass: add each element into its parent's children array
foreach( $data as $o ){
$pid = $o->idParent ? $o->idParent : '*';
$p = $by_id[ $pid ];
$p->children[] = $o;
}
// Trash everything else, we start from the (fake) root element:
$tree = $by_id['*']->children;
/**** REVERSE ****/
$todo = $tree;
$json = array();
while( $todo ){
$o = array_shift( $todo );
if( isset( $o->children )){
$todo = array_merge( $todo, $o->children );
unset( $o->children );
}
$json[] = $o;
};
echo json_encode( $json );
The result:
http://codepad.viper-7.com/V7PjDh
array:
array(
['name'=>'kevin','value'=>'10'],
['name'=>'sam','value'=>'20']
);
how can i return value where name='sam' for example ?
and what how can i do it in even deeper array
array(
[0]=>array( 'inputs'=>
array(['name'=>'kevin','value'=>'10'],['name'=>'sam','value'=>'20']
),
[1]=>array( 'inputs'=>
array(['name'=>'kim','value'=>'10'],['name'=>'kirki','value'=>'20']
)
);
you need a recursive array_search - all answers above handle an exact amount of depth (in this case 2) only.
something like
function recursive_array_search($needle,$haystack) {
foreach ($haystack as $key=>$value) {
if ($needle===$value OR (is_array($value) && recursive_array_search($needle,$value) !== false)) {
return $value['value'];
}
}
return false;
}
recursive_array_search('sam', $start_array);
$arr = array(
array("name"=>"A","info"=>"one"),
array("name"=>"B","info"=>"two"),
array("name"=>"C","info"=>"three")
);
foreach($arr as $v){
if ($v['name']==="A"){
echo $v['info'];
}
}
In Deep Level
$arr = array(
array("input"=>array(
"name"=>"A",
"info"=>"one"
)),
array("input"=>array(
"name"=>"B",
"info"=>"Two"
))
);
foreach($arr as $subarr){ // First foreach iterate through arrays and next foreach iterate through values of each sub array
foreach($subarr as $v){
if ($v['name']==="A"){
echo $v['info'];
}
}
}
for($i=0;$i<count($array);$i++)
{
if($array['name']=="sam")
{
echo $array['value'];
}
}
and for next array you can do like this....
for($i=0;$i<count($array);$i++)
{
for($j=0;$j<count($array[$i]['inputs']);$j++)
{
if($array[$i]['inputs'][$j]['name']=="sam")
{
echo $array[$i]['inputs'][$j]['info'];
}
}
}
$new_array = array();
foreach ($old_array as $value) {
$new_array[$value['name']] = $value['value'];
}
var_dump($new_array['kevin']); // prints 10
I have a multi-dimension array like:
$fields =
Array (
[1] => Array
(
[field_special_features5_value] => Special Function 5
)
[2] => Array
(
[field_special_features6_value] => Special Function 6
)
[3] => Array
(
[field_opticalzoom_value] => Optical Zoom
)
)
I want to get the value by key, I tried the code below but not work
$tmp = array_search('field_special_features5_value' , $fields);
echo $tmp;
How can I get the value Special Function 5 of the key field_special_features5_value?
Thanks
print $fields[1]['field_special_features5_value'];
or if you don't know at which index your array is, something like this:
function GetKey($key, $search)
{
foreach ($search as $array)
{
if (array_key_exists($key, $array))
{
return $array[$key];
}
}
return false;
}
$tmp = GetKey('field_special_features5_value' , $fields);
echo $tmp;
If you know where it is located in the $fields array, try :
$value = $fields[1]['field_special_features5_value'];
If not, try :
function getSubkey($key,$inArray)
{
for ($fields as $field)
{
$keys = array_keys($field);
if (isset($keys[$key])) return $keys[$key];
}
return NULL;
}
And use it like this :
<?php
$value = getSubkey("field_special_features5_value",$fields);
?>
You need to search recursive:
function array_search_recursive(array $array, $key) {
foreach ($array as $k => $v) {
if (is_array($v)) {
if($found = array_search_recursive($v, $key)){
return $found;
}
} elseif ($k == $key) {
return $v;
} else {
return false;
}
}
}
$result = array_search_recursive($fields, 'field_special_features5_value');
Your problem is that you have a top-level index first before you can search you array. So to access that value you need to do this:
$tmp = $fields[1]['field_special_features5_value'];
You can do it with recursive function like this
<?php
function multi_array_key_exists($needle, $haystack) {
foreach ($haystack as $key=>$value) {
if ($needle===$key) {
return $key;
}
if (is_array($value)) {
if(multi_array_key_exists($needle, $value)) {
return multi_array_key_exists($needle, $value);
}
}
}
return false;
}
?>