Parse array to get required data - php

I have an input array like this:
Array
(
[one] => one
[two] => two
[group1] => Array
(
[three] => three
[four] => four
[group2] => Array
(
[five] => five
)
)
[group3] => Array
(
[six] => six
)
)
I want to extract following 6 strings from above array:
Array
(
[0] => one
[1] => two
[2] => group1,three
[3] => group1,four
[4] => group1,group2,five
[5] => group3,six
)
Any Idea? Is there any useful PHP function for this?
I have tried something like this:
function getStrings( $data, &$result, $parent = '' ) {
foreach( $data as $key => $value ) {
if( is_array( $value ) ) {
getStrings( $value, $result, $key );
} else {
if( $parent == '' ) {
$result[] = $value;
} else {
$result[] = $parent . ',' . $value;
}
}
}
}
$tree = array();
getStrings( $input, $tree );
print_r( $tree );
Result:
Array
(
[0] => one
[1] => two
[2] => group1,three
[3] => group1,four
[4] => group2,five
[5] => group3,six
)

According to your data structure which is:
$data = [
'one' => 'one',
'two' => 'two',
'group1' => [
'three' => 'three',
'four' => 'four',
'group2' => ['five']
],
'group3' => ['six' => 'six']
];
You can use Recursive function:
function make_implode($data){
$rows = [];
foreach($data as $key => $val) {
if(is_array($val)) {
//$rows[] = $key;
$nestedData = make_implode($val);
if(is_array($nestedData)){
foreach($nestedData as $keyNested => $valNested) {
$rows[] = $key.','.$valNested;
}
} else {
$rows[] = $key.','.$nestedData;
}
} else {
$rows[] = $val;
}
}
return $rows;
}
$data = make_implode($data);
echo '<pre>'.print_r($data,1).'</pre>';
//prints
Array
(
[0] => one
[1] => two
[2] => group1,three
[3] => group1,four
[4] => group1,group2,five
[5] => group3,six
)

use a recursive function, similar to:
$a = array("one"=>"one","group1"=>array("three"=>"three"));
var_dump($a);
function recFor($a) {
foreach($a as $k => $v) {
if(is_array($v)) {
$tmp= recFor($v);
$res[] = $tmp[0];
} else {
$res[] = $v;
}
}
return $res;
}
$b = recFor($a);
var_dump($b);
This is just a quick and dirty example, but you should get the idea.

Related

Merge Parent child array

I have PHP array. I am trying to convert into a parent-child array:
I have used a recursive function but not getting my output.
Array
(
[0] => Array
(
[id] => 1
[subscription_name] => Yearly
[parent_id] => 0
)
[1] => Array
(
[id] => 22
[subscription_name] => Yearly new
[parent_id] => 1
)
[2 => Array
(
[id] => 23
[subscription_name] => Yearly new offer
[parent_id] => 22
)
[3] => Array
(
[id] => 24
[subscription_name] => Weekly
[parent_id] => 0
)
[4] => Array
(
[id] => 25
[subscription_name] => Weekly new offer
[parent_id] => 24
)
)
I expect this result
Array
(
[0] => Array
(
[id] => 1
[subscription_name] => Yearly new offer
[childrens] => Array
(
[0] => Array
(
[id] => 22
)
[1] => Array
(
[id] => 23
)
)
)
[1] => Array
(
[id] => 24
[subscription_name] => Weekly new offer
[childrens] => Array
(
[0] => Array
(
[id] => 25
)
)
)
)
I have tried but not getting my desire Output
My PHP function is
function tree(array $elements, $parent_id = 0) {
echo "<pre>";
$branch = array();
$a=array();
foreach ($elements as $element) {
if ($element['parent_id'] == $parent_id && $element['subscription_type_id'] !=1 ) {
$children = $this->tree($elements, $element['id']);
if ($children) {
$element['children'] = $children;
}
else {
$element['children'] = array();
}
$branch[] = $element;
}
}
return $branch;
}
Here is the output I am getting from the above function:
Array
(
[0] => Array
(
[id] => 1
[subscription_name] => Yearly
[children] => Array
(
[0] => Array
(
[id] => 22
[subscription_name] => Yearly new
[children] => Array
(
[0] => Array
(
[id] => 23
[subscription_name] => Yearly new offer
[children] => Array
(
)
)
)
)
)
)
[1] => Array
(
[id] => 24
[subscription_name] => Weekly
[children] => Array
(
[0] => Array
(
[id] => 25
[subscription_name] => Weekly new offer
[children] => Array
(
)
)
)
)
Please help me to solve this problem.
Thanks.
Really, i mean REALLY naive version but by the way, your data would be really more easy to exploit, like don't have any parent_id to 0 if it's not a parent Id (NULL for example) I also do not understand why do you have different subscription_name. I think you should work more on change your input instead of find a complexe algorithm to parse them
function tree(array $elements) {
$openList = [];
$result = [];
$id = 0;
foreach ($elements as $key => $element) {
if($key != 0) // I suppose the trial one is not used
{
if($element['parent_id'] == 0) // a root
{
$closeList = [];
$openList[$element['id']] = $element['id'];
$result[$id] = $element;
unset($result[$id]['parent_id']);
$result[$id]['children'] = [];
$newOpenlist = [];
while(count($openList) > 0)
{
foreach ($elements as $key => $element) {
if($element['parent_id'] != 0 && in_array($element['parent_id'], $openList) && !in_array($element['parent_id'], $closeList))
{
$newOpenlist[$element['id']] = $element['id'];
$result[$id]['children'][] = $element;
}
}
foreach($openList as $item)
{
$closeList[] = $item;
}
$openList = $newOpenlist;
$newOpenlist = [];
}
}
$id++;
}
}
return $result;
}
From your question, I do not clearly understand the logic behind the subscription_name. Regarding the childrens below code might work.
<?php
$array = [
[
'id' => 1,
'subscription_name' => 'Yearly',
'parent_id' => 0
],
[
'id' => 22,
'subscription_name' => 'Yearly new',
'parent_id' => 1
],
[
'id' => 23,
'subscription_name' => 'Yearly new offer',
'parent_id' => 22
],
[
'id' => 24,
'subscription_name' => 'Weekly',
'parent_id' => 0
],
[
'id' => 25,
'subscription_name' => 'Weekly new offer',
'parent_id' => 24
],
];
function find_childrens_parent_not_zero($array) {
foreach($array as $key => $value) {
if($value['parent_id'] != 0) {
if(!is_array($array[$key]['childrens'])) {
$array[$key]['childrens'] = [];
}
foreach($array as $k => $v) {
if($v['parent_id'] == $value['id']) {
array_push($array[$key]['childrens'], array('id' => $v['id']));
unset($array[$k]['parent_id']);
}
}
}
}
return $array;
}
function find_childrens_parent_zero($array) {
foreach($array as $key => $value) {
if($value['parent_id'] == 0) {
if(!is_array($array[$key]['childrens'])) {
$array[$key]['childrens'] = [];
}
foreach($array as $k => $v) {
if($v['parent_id'] == $value['id']) {
array_push($array[$key]['childrens'], array('id' => $v['id']));
unset($array[$k]['parent_id']);
}
}
}
}
return $array;
}
function merge_children($array) {
foreach($array as $key => $value) {
if($value['parent_id'] == 0) {
//pluck childrens of it's children
foreach($value['childrens'] as $k => $v) {
foreach($array as $ke => $val) {
if($v['id'] == $val['id']) {
$array[$key]['childrens'] = array_merge($array[$key]['childrens'], $array[$ke]['childrens']);
}
}
}
}
}
return $array;
}
/**
* Remove parent not zero elements
*/
function cleanup_array($array) {
$result = [];
foreach($array as $key => $value) {
if(array_key_exists('parent_id', $value )) {
unset($value['parent_id']);
array_push($result, $value);
}
}
return $result;
}
echo '<pre>';
$result_parent_not_zero = find_childrens_parent_not_zero($array);
$result_parent_zero = find_childrens_parent_zero($result_parent_not_zero);
$result_merged_children = merge_children($result_parent_zero);
$result_cleaned_up = cleanup_array($result_merged_children);
print_r($result_cleaned_up);
Will give you the result as
<pre>Array
(
[0] => Array
(
[id] => 1
[subscription_name] => Yearly
[childrens] => Array
(
[0] => Array
(
[id] => 22
)
[1] => Array
(
[id] => 23
)
)
)
[1] => Array
(
[id] => 24
[subscription_name] => Weekly
[childrens] => Array
(
[0] => Array
(
[id] => 25
)
)
)
)
<?php
$load[0]['id'] = 0;
$load[0]['subscription_name'] = 'Trial';
$load[0]['parent_id'] = 0;
$load[1]['id'] = 1;
$load[1]['subscription_name'] = 'Yearly';
$load[1]['parent_id'] = 0;
$load[2]['id'] = 2;
$load[2]['subscription_name'] = 'Trial';
$load[2]['parent_id'] = 1;
$load[3]['id'] = 3;
$load[3]['subscription_name'] = 'Yearly';
$load[3]['parent_id'] = 1;
$load[4]['id'] = 4;
$load[4]['subscription_name'] = 'Trial';
$load[4]['parent_id'] = 2;
function tree($load){
$output = [];
foreach($load as $l){
$temp = [];
foreach($load as $ll){
if($ll['parent_id']==$l['id']){
if($l['id']==$ll['id'])
continue;
$temp[] = $ll;
}
}
$l['childrens'] = $temp;
$output[] = $l;
}
return $output;
}
echo "<pre>";
print_r(tree($load));

multidimensional array store each list array inside another array

I have nested multidimensional arrays that may be 2 or 3 levels deep. Inside it I may or may not have list arrray. I need to loop over the array:
Array
(
[0] => Array
(
[id] => 1
[name] => cat_name_1
[list] => Array
(
[1] => swgdgbdg
[2] => xcbcxb
)
)
[1] => Array
(
[id] => 3
[name] => cat_name_3
[list] => Array
(
[0] => Array
(
[id] => 1
[name] => cat_name_1
[list] => Array
(
[1] => 543h54h
[2] => 54hrhhfr2
)
)
[1] => Array
(
[id] => 2
[name] => cat_name_2
[list] => Array
(
[1] => eherfherh
[2] => 4564642
)
)
[2] => Array
(
[1] => erggb45yt
[2] => jyuk768k
)
[3] => Array
(
[1] => sdgsdgsdg
[2] => 4tg34g34g
)
)
)
and store the following in another array:
array (
0 => array (
[1] => swgdgbdg
[2] => xcbcxb
) ,
1 => array(
[1] => 543h54h
[2] => 54hrhhfr2
) ,
2 => array(
[1] => eherfherh
[2] => 4564642
),
3 => array(
[1] => erggb45yt
[2] => jyuk768k
),
4 => array(
[1] => sdgsdgsdg
[2] => 4tg34g34g
)
);
You can use array_walk_recursive() to get the key 1,2 and are not array element, like this, check the live demo here.
$result = [];
$temp = [];
array_walk_recursive($array, function($v, $k) use(&$result, &$temp){
if($k == 1)
$temp[$k] = $v;
if($k == 2)
{
$temp[$k] = $v;
$result[] = $temp;
}
});
print_r($result);
Edit for unfixed length and unordered index, live demo.
Extend the array_walk_recursive() with a third parameter for the callfunction to indicate if it's at the start of an subarray.
$result = [];
$temp = [];
$length = 0;
uarray_walk_recursive($array, function($v, $k, $f) use(&$result, &$temp, &$length){
if(is_numeric($k)) {
if($f && $length != 0) {
$result[] = $temp;
$length = 0;
$temp = [];
}
$temp[$k] = $v;
$length++;
}
});
$result[] = $temp;
print_r($result);
function uarray_walk_recursive(&$input, $funcname)
{
if (!is_callable($funcname)) {
if (is_array($funcname)) {
$funcname = $funcname[0] . '::' . $funcname[1];
}
user_error('uarray_walk_recursive() Not a valid callback ' . $user_func,
E_USER_WARNING);
return;
}
if (!is_array($input)) {
user_error('uarray_walk_recursive() The argument should be an array',
E_USER_WARNING);
return;
}
$args = func_get_args();
$flag = true;
foreach ($input as $key => $item) {
if (is_array($item)) {
$args[2] = false;
$flag = true;
uarray_walk_recursive($item, $funcname, $args);
$input[$key] = $item;
} else {
$args[2] = $flag;
$flag = false;
$args[0] = &$item;
$args[1] = &$key;
call_user_func_array($funcname, $args);
$input[$key] = $item;
}
}
}
PseudoCode
function getSomething(var arr)
{
flag = 0;
output = []
for( i = 0 to arr.length)
{
check arr[i] is array,
if yes,then flag = 1 and output.add(getSomething(arr[i]))
if not, continue
}
if flag =0,then return arr
else return output;
}

2 dimensional array to sort using PHP

MY CODE IS :
$arr = array(
array(
"title" => "Volvo"
),
array(
"title" => "BMW"
),
array(
"title" => "Saab"
),
array(
"title" => "Aam"
)
);
$a = aasort($arr,"title");
echo "<pre>",print_r($a),"</pre>";
function aasort (&$array, $key) {
$sorter=array();
$ret=array();
reset($array);
foreach ($array as $ii => $va) {
$sorter[$ii]=$va[$key];
}
natcasesort($sorter);
foreach ($sorter as $ii => $va) {
$ret[$ii]=$array[$ii];
}
$array=$ret;
return $array;
}
and the output is :
Array
(
[3] => Array
(
[title] => Aam
)
[1] => Array
(
[title] => BMW
)
[2] => Array
(
[title] => Saab
)
[0] => Array
(
[title] => Volvo
)
)
1
But i want output like :
Array
(
[0] => Array
(
[title] => Aam
)
[1] => Array
(
[title] => BMW
)
[2] => Array
(
[title] => Saab
)
[3] => Array
(
[title] => Volvo
)
)
1
How to do it ?
You can reindex an array with array_values():
$array = array_values($ret);
Try this it will help you :
$result = array();
$result = sortArray($array,'key');
Here, $array is unsorted array. So you can sort it by call sortArray function.
<?php
function sortArray($arrData, $p_sort_field, $p_sort_type = false )
{
if(!empty($arrData))
{
foreach($arrData as $data)
{
$newData [] = $data;
}
for($i=0; $i<count($newData); $i++)
{
$ar_sort_field[$i]=$newData[$i][$p_sort_field];
}
array_multisort($ar_sort_field, ($p_sort_type ? SORT_DESC : SORT_ASC), $newData);
return $newData;
}
}
?>
Try this..
$arr = array(
array(
"title" => "Volvo"
),
array(
"title" => "BMW"
),
array(
"title" => "Saab"
),
array(
"title" => "Aam"
)
);
$arr = msort($arr, array('title'));
print_r($arr);
function msort($array, $key, $sort_flags = SORT_REGULAR) {
if (is_array($array) && count($array) > 0) {
if (!empty($key)) {
$mapping = array();
foreach ($array as $k => $v) {
$sort_key = '';
if (!is_array($key)) {
$sort_key = $v[$key];
} else {
// #TODO This should be fixed, now it will be sorted as string
foreach ($key as $key_key) {
$sort_key .= $v[$key_key];
}
$sort_flags = SORT_STRING;
}
$mapping[$k] = $sort_key;
}
asort($mapping, $sort_flags);
$sorted = array();
foreach ($mapping as $k => $v) {
$sorted[] = $array[$k];
}
return $sorted;
}
}
return $array;
}
Result
Array ( [0] => Array ( [title] => Aam ) [1] => Array ( [title] => BMW )
[2] => Array ( [title] => Saab ) [3] => Array ( [title] => Volvo ) )`

PHP Change array to one dimension

Function to generate array format:
function buildTree(array $elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
if ($element['parent_id'] == $parentId) {
$children = buildTree($elements, $element['id']);
if ($children) {
$element['children'] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
$tree = buildTree($rows);
Array generated:
Array
(
[0] => Array
(
[TASK_ID] => 2
[PARENT_TASKID] => 0
[TASK_LEVEL] => 0
[children] => Array
(
[0] => Array
(
[TASK_ID] => 9
[PARENT_TASKID] => 2
[TASK_LEVEL] => 1
)
[1] => Array
(
[TASK_ID] => 10
[PARENT_TASKID] => 2
[TASK_LEVEL] => 1
)
)
)
[1] => Array
(
[TASK_ID] => 1
[PARENT_TASKID] => 0
[TASK_LEVEL] => 0
[children] => Array
(
[0] => Array
(
[TASK_ID] => 4
[PARENT_TASKID] => 1
[TASK_LEVEL] => 1
)
[1] => Array
(
[TASK_ID] => 5
[PARENT_TASKID] => 1
[TASK_LEVEL] => 1
[children] => Array
(
[0] => Array
(
[TASK_ID] => 6
[PARENT_TASKID] => 5
[TASK_LEVEL] => 2
)
)
)
)
)
)
How can I change the above format into below:
Array
(
[0] => Array
(
[TASK_ID] => 2
[PARENT_TASKID] => 0
)
[1] => Array
(
[TASK_ID] => 9
[PARENT_TASKID] => 2
)
[2] => Array
(
[TASK_ID] => 10
[PARENT_TASKID] => 2
)
)
Tried below code:
$flat = call_user_func_array('array_merge', $array);
and
$array = your array
$result = call_user_func_array('array_merge', $array);
echo "<pre>";
print_r($result);
But does not seem to work. Please Help.
Thanks.
You should use a recursive function to flatten the tree as you have used a recursive function to build the tree.
function flattenTree($tree)
{
$flat = array();
foreach ($tree as $item) {
if (array_key_exists('children', $item)) {
$children = $item['children'];
unset($item['children']);
$flat[] = $item;
$flat = array_merge($flat, flattenTree($children));
} else {
$flat[] = $item;
}
}
return $flat;
}
$flat = flattenTree($tree);
<?php
$arr = array();
$i = 0;
foreach ($your_array[0] as $k => $v) {
if ($k == 'TASK_ID' OR $k == 'PARENT_TASKID') {
$arr[$i][$k] = $v;
}
$i++;
}
?>
Try output:
<?php
echo '<pre>';
print_r($arr);
echo '</pre>';
?>
Hope, it works for you.
I have been using this for $_FILES parsing when capturing multiple files
function multi_array($array)
{
$new = array();
foreach($array as $key=>$elem)
{
if(is_array($elem))
{
foreach($elem as $x=>$val)
{
if(!is_array($val))
{
$new[$x][$key] = $val;
}
}
}
}
return $new;
}
Usage is pretty basic
$array = multi_array($array);
I hope it helps
Try with below code :
function makeOneDimensionArray(array $array, &$res = array())
{
foreach($array as $arr)
{
$res[] = array(
'TASK_ID' => $arr['TASK_ID'],
'PARENT_TASKID' => $arr['PARENT_TASKID']
);
if(isset($arr['children']))
{
makeOneDimensionArray($arr['children'], $res);
}
}
return $res;
}
$finalArr = makeOneDimensionArray($array);
print_r($finalArr);
I hope it help.

How to keep this element in this array?

I have the following array.
array(
[PM-AAA] => Array
(
[codePm] => PM-32249
[codeArt] => Array
(
[0] => 32249
)
[codeArtInFlux] => Array
(
[0] => 123456
)
)
[PM-BBB] => Array
(
[codePm] => PM-32249
[codeArt] => Array
(
[0] => 33270
)
[codeArtInFlux] => Array
(
[0] => 484946
)
)
[PM-CCC] => Array
(
[codePm] => PM-82242
[codeArt] => Array
(
[0] => 82242
[1] => 82245
[2] => 82246
)
[codeArtInFlux] => Array
(
[0] => 5191
[1] => 51949
[2] => 26486
)
)
)
I want keep the array where the "codePm" value is unique. For exemple, in the above array, the "PM-CCC" array will be keep, because the "codePm" is unique, contrary to the "PM-AAA" and "PM-BBB", which share the same "codePm"'s value.
Is it possible to do it with one function ?
As I know, there isn't any function that do it directly, you can try this:
function insert_unique_key($key_name,$elem,&$array) {
//Get all elements with the key
$values=array()
foreach ($array as $ii) {
$values[]=$ii[$key_name];
}
//Check if the value exists
if (in_array($elem[$key_name], $values)===FALSE) {
$array[]=$elem;
}
}
And in your code:
insert_unique_key('codePm',$elem_to_insert,$array_of_elements);
And you have to do it for each element of your array into a new array
--
EDIT: Sorry, this is for insert new unique values into the array, not for obtain the unique values.
Looking at the comments, I think you want only unique values Try this function:
function get_uniques_by_subkey($key_name,$array) {
//Get all elements with the key
$values=array();
foreach ($array as $ii) {
$values[]=$ii[$key_name];
}
//Get the elements that only appeared one time
$count=array_count_values($values);
unset($values);$values=array();
foreach ($count as $key => $n) {
if ($n==1)
$values[]=$key;
}
//Get the values
$out=array();
foreach ($array as $key => $value) {
if (in_array($value[$key_name],$values))
$out[$key]=$value;
}
return $out;
}
You can check the result here: http://codepad.org/QmuoYxsk
Something like this ?
<?
function removeDuplicatesByKey($a, $k) {
$r = array();
$tmp = array();
foreach ($a as $ind => $arr) {
$elem_found = array_search($arr[$k], $tmp);
if ($elem_found === false) {
$tmp[] = $arr[$k];
$r[$ind] = $arr;
} else {
// ok, element found, need to remove both ..
foreach ($r as $index => $r_arr) {
if ($r_arr[$k] == $arr[$k]) {
unset($r[$index]);
}
}
}
}
return $r;
}
$full_arr = array(
'PM-AAA' => array
(
'codePm' => 'PM-32249',
'codeArt' => array(
'0' => 32249
),
'codeArtInFlux' => array(
'0' => 123456
)
)
,
'PM-BBB' => array
(
'codePm' => 'PM-32249',
'codeArt' => array
(
'0' => 33270
),
'codeArtInFlux' => array
(
'0' => 484946
)
)
,
'PM-CCC' => array
(
'codePm' => 'PM-82242',
'codeArt' => array
(
'0' => 82242,
'1' => 82245,
'2' => 82246
),
'codeArtInFlux' => array
(
'0' => 5191,
'1' => 51949,
'2' => 26486
)
)
);
print_r(removeDuplicatesByKey($full_arr, 'codePm'));
?>
Output
Array
(
[1] => Array
(
[codePm] => PM-82242
[codeArt] => Array
(
[0] => 82242
[1] => 82245
[2] => 82246
)
[codeArtInFlux] => Array
(
[0] => 5191
[1] => 51949
[2] => 26486
)
)
)
I made this....on speed mode in my work....you can improve it ;)
$array = array(
'PM-AAA' => array(
'codePm' => 'PM-32249',
'codeArt' => array(32249),
'codeArtInFlux' => array(123456)
),
'PM-BBB' => array(
'codePm' => 'PM-32249',
'codeArt' => array(33270 ),
'codeArtInFlux' => array(484946)
),
'PM-CCC' => array(
'codePm' => 'PM-82242',
'codeArt' => array(82242,82245,82246),
'codeArtInFlux' => array(5191,51949,26486)
)
);
$code_count = array();
$arr2 = array();
foreach($array as $counter) {
$key = $counter['codePm'];
$code_count[] = $key;
}
$arr2 = (array_count_values($code_count));
print_r($arr2); //now i know how many times my code is repeated
while ($code_name = current($arr2)) {
if ($code_name == 1) {
$unique_code = key($arr2);
}
next($arr2);
}
echo $unique_code."</br>"; //i have my unique code
foreach ($array as $key) {
var_dump($key);
if($key['codePm']==$unique_code)
$arr_aux = $key;
}
echo "I have mi array ready with the unique val ;) </br>";
var_dump($arr_aux);
Saludos ;)

Categories