Get all data in a line using recursive function from an array - php

I have an array like this
Array
(
[0] => Array
(
[id] => 1
[category_name] => One
[parent_id] =>
[children_recursive] => Array
(
)
)
[1] => Array
(
[id] => 2
[category_name] => Two
[parent_id] =>
[children_recursive] => Array
(
)
)
[2] => Array
(
[id] => 3
[category_name] => Three
[parent_id] =>
[children_recursive] => Array
(
[0] => Array
(
[id] => 17
[category_name] => Three and one
[parent_id] => 3
[children_recursive] => Array
(
)
)
[1] => Array
(
[id] => 19
[category_name] => Three and two
[parent_id] => 3
[children_recursive] => Array
(
[0] => Array
(
[id] => 21
[category_name] => Three and two and one
[parent_id] => 19
[children_recursive] => Array
(
)
)
)
)
[2] => Array
(
[id] => 20
[category_name] => Three and three
[parent_id] => 3
[children_recursive] => Array
(
)
)
)
)
[3] => Array
(
[id] => 4
[category_name] => Four
[parent_id] =>
[children_recursive] => Array
(
[0] => Array
(
[id] => 18
[category_name] => Four and one
[parent_id] => 4
[children_recursive] => Array
(
)
)
)
)
)
What I want to from this array
One
Two
Three
Three >> Three and one
Three >> Three and two
Three >> Three and two >> Three and two and one
Three >> Three and three
Four
Four >> Four and one
What I have tried
$category = myarray;
renderNode($category);
function renderNode($node) {
foreach($node as $cat){
echo $cat['category_name'].'<br >';
if(!empty($cat[children_recursive'])){
renderNode($cat[children_recursive']);
}
}
}
And My output is
One
Two
Three
Three and one
Three and two
Three and two and one
Three and three
Four
Four and one
Edit
here is the full array list using var_export so you can just copay and paste
array (
0 =>
array (
'id' => 1,
'category_name' => 'One',
'parent_id' => NULL,
'children_recursive' =>
array (
),
),
1 =>
array (
'id' => 2,
'category_name' => 'Two',
'parent_id' => NULL,
'children_recursive' =>
array (
),
),
2 =>
array (
'id' => 3,
'category_name' => 'Three',
'parent_id' => NULL,
'children_recursive' =>
array (
0 =>
array (
'id' => 17,
'category_name' => 'Three and one',
'parent_id' => 3,
'children_recursive' =>
array (
),
),
1 =>
array (
'id' => 19,
'category_name' => 'Three and two',
'parent_id' => 3,
'children_recursive' =>
array (
0 =>
array (
'id' => 21,
'category_name' => 'Three and two and one',
'parent_id' => 19,
'children_recursive' =>
array (
),
),
),
),
2 =>
array (
'id' => 20,
'category_name' => 'Three and three',
'parent_id' => 3,
'children_recursive' =>
array (
),
),
),
),
3 =>
array (
'id' => 4,
'category_name' => 'Four',
'parent_id' => NULL,
'children_recursive' =>
array (
0 =>
array (
'id' => 18,
'category_name' => 'Four and one',
'parent_id' => 4,
'children_recursive' =>
array (
),
),
),
),
)

Something like that:
function getValues($array, $prefix = '')
{
$values = [];
foreach ($array as $value) {
$values[] = $prefix . $value['category_name'];
if (!empty($value['children_recursive'])) {
$values = array_merge($values, getValues($value['children_recursive'], $prefix . $value['category_name'] . ' >> '));
}
}
return $values;
}
implode('<br>', getValues($array));

You can use RecursiveArrayIterator. You need to extend it like this:
class RecursiveChildrenIterator extends RecursiveArrayIterator
{
public function hasChildren()
{
return !empty($this->current()['children_recursive']);
}
public function getChildren()
{
return new static($this->current()['children_recursive']);
}
}
Having this class you can simply loop with one foreach:
$iterator = new RecursiveIteratorIterator(
new RecursiveChildrenIterator($array),
RecursiveIteratorIterator::SELF_FIRST
);
$result = [];
$current = [];
foreach ($iterator as $item) {
$current[$iterator->getDepth()] = $item['category_name'];
if (!$iterator->hasChildren()) {
$result[] = implode(
'>>',
array_slice($current, 0, $iterator->getDepth() + 1)
);
}
}
Take a notice on RecursiveIteratorIterator::SELF_FIRST flag passed to RecursiveIteratorIterator.
Here is working demo.
Addition:
I actually misread you desired array, so to get the one you wanted remove the condition:
foreach ($iterator as $item) {
$current[$iterator->getDepth()] = $item['category_name'];
$result[] = implode(
'>>',
array_slice($current, 0, $iterator->getDepth() + 1)
);
}
Here is working demo.
You can read more about iterators.

$category = myarray;
renderNode($category);
function renderNode($parent_category_name = '' ,$node) {
foreach($node as $cat){
echo $parent_category_name.$cat['category_name'].'<br >';
if(!empty($cat[children_recursive'])){
renderNode($parent_category_name .$cat['category_name'] ." >> ", $cat[children_recursive']);
}
}
}

Related

Combine value array in php

i have problem to combine values based on id.
I have data like this :
Array(
[0] => Array(
[id] => 1,
[id_name] => a
[id_vales] => 5
)
[1] => Array(
[id] => 1
[id_name] => a
[id_vales] => 4
)
[2] => Array(
[id] => 3
[id_name] => b
[id_vales] => 4
)
[3] => Array(
[id] => 3
[id_name] => b
[id_vales] => 3
)
)
then, i want combine [id_values] based on id, so i can get data like this in php
Array(
[0] => Array(
[id] => 1
[id_name] => a
[id_vales] => 5, 4
)
[1] => Array(
[id] => 3
[id_name] => b
[id_vales] => 4, 3
)
)
You can use the following example to merge your array
<?php
$mainArray = array(array('id' => 1, 'id_name' => 'a', 'id_vales' => 5),
array('id' => 1,'id_name' => 'a','id_vales' => 4),
array('id' => 3, 'id_name' => 'b','id_vales' => 4),
array('id' => 3,'id_name' => 'b','id_vales' => 3)
);
$result = array();
$tempArray = array();
foreach($mainArray as $key => $value)
{
if(isset($tempArray[$value['id']]))
{
$tempArray[$value['id']] .= ", ".$value['id_vales'];
$result[] = array('id' => $value['id'], 'id_name' => $value['id_name'], 'id_vales' => $tempArray[$value['id']]);
}
else
{
$tempArray[$value['id']] = "".$value['id_vales'];
}
}
echo "<pre>";
print_r($result);
?>
You can find running example here https://paiza.io/projects/3sS3GXH7GHqoipH8k-YtBQ
Output:
Array
(
[0] => Array
(
[id] => 1
[id_name] => a
[id_vales] => 5, 4
)
[1] => Array
(
[id] => 3
[id_name] => b
[id_vales] => 4, 3
)
)
I have created an array for you. from this array you can easily create your array and get the result.
$data = array();
foreach($array as $key=>$value){
$data[$value['id']]['id'] = $value['id'];
$data[$value['id']]['id_vales'][] = $value['id_vales'];
$data[$value['id']]['id_name'] = $value['id_name'];
}

How to get Php multidimensional array same key’s same value’s related total in new array?

Php multidimensional array same key’s same value’s related total in
new array. I have an array of following mentioned. i need new array
as total qty of same item_id. anyone can help would be appreciate.
My Original Array is as following
Array
(
[a] => Array
(
[item] => Array
(
[item_id] => 1
)
[qty] => 0
),
[b] => Array
(
[item] => Array
(
[item_id] => 2
)
[qty] => 35
),
[c] => Array
(
[item] => Array
(
[item_id] => 2
)
[qty] => 15
),
[e] => Array
(
[item] => Array
(
[item_id] => 3
)
[qty] => 20
),
);
I want array Output like following :
Array(
[0] => Array (
[item_id] => 1,
[item_total_qty] => 0,
)
[1] => Array (
[item_id] => 2,
[item_total_qty] => 50,
)
[2] => Array (
[item_id] => 3,
[item_total_qty] => 20,
)
);
Hope it help
$arrays = array(
'a' => array(
'item' => array(
'item_id' => 1
),
'qty' => 0
),
'b' => array(
'item' => array(
'item_id' => 2
),
'qty' => 35
),
'c' => array(
'item' => array(
'item_id' => 2
),
'qty' => 15
),
'd' => array(
'item' => array(
'item_id' => 3
),
'qty' => 20
)
);
$result = array();
foreach ($arrays as $key => $array) {
if (is_array($result) && !empty($result)) {
foreach ($result as $key => $r) {
if ($r['item_id'] == $array['item']['item_id']) {
$result[$key]['item_total_qty'] += $array['qty'];
continue 2;
}
}
$result[] = array(
'item_id' => $array['item']['item_id'],
'item_total_qty' => $array['qty']);
} else {
$result[] = array(
'item_id' => $array['item']['item_id'],
'item_total_qty' => $array['qty']);
}
}
Simple foreach on your original table:
$sorted = array();
foreach ($original as $item) {
$id = $item['item']['item_id'];
$sorted[$id]['item_total_qty'] = $sorted[$id] ? $sorted[$id] + $item['qty'] : item['qty'];
$sorted[$id]['item_id'] = $id;
}
$sorted = array_values($sorted);

How to convert a recursive multidimensional array to a straight multidimensional array in PHP?

I have search for a solution for this but couldn't find anything giving me a "straight" multidimensional array back. Flatten is probably not the solution as long as i want to preserve the original sub structure?
In additional i want to summarize qty when the key is repeating.
This is my original array:
Array
(
[60002] => Array
(
[50001] => Array
(
[50002] => Array
(
[10001] => Array
(
[flag] => B
[qty] => 1
)
[10002] => Array
(
[flag] => B
[qty] => 1
)
[10003] => Array
(
[flag] => B
[qty] => 2
)
[flag] => M
[qty] => 1
)
[flag] => M
[qty] => 1
)
[flag] => G
[qty] => 1
)
[10001] => Array
(
[flag] => B
[qty] => 1
)
)
What i basically want is to create a new array looking like this:
Array
(
[10001] => Array
(
[flag] => B
[qty] => 2
)
[10002] => Array
(
[flag] => B
[qty] => 1
)
[10003] => Array
(
[flag] => B
[qty] => 2
)
[50001] => Array
(
[flag] => M
[qty] => 1
)
[50002] => Array
(
[flag] => M
[qty] => 1
)
[60002] => Array
(
[flag] => G
[qty] => 1
)
)
This is tested.
The key is intval().
$value['qty'] += intval($newArray[$key]['qty']);
If the [$key]['qty'] does not exist the intval() will return a zero. This is much faster than using an if else to check if a [$key]['qty'] already exists.
The only possible problem I could anticipate is if the Flag value is different when the key value is the same:
[10001] => Array(
[flag] => M
[qty] => 1
),
[10001] => Array(
[flag] => B
[qty] => 1
)
When this is an issue I resolve the priority with a logic table in an array.
$priority['M']['B'] = 'M'
$priority['B']['M'] = 'M'
$priority['']['M'] = 'M'
$priority['M'][''] = 'M'
$priority['B'][''] = 'B'
$priority['B'][''] = 'B'
settype($newArray[$key]['flag'],'string');
[$newArray[$key]['flag'] = $priority[$value['flag']][$newArray[$key]['flag']]
Data:
$array = array('60002' => Array('50001' => Array('50002' => Array('10001' => Array('flag' => 'B','qty' => 1),'10002' => Array('flag' => 'B','qty' => 1),'10003' => Array('flag' => 'B','qty' => 2),'flag' => 'M','qty' => 1),'flag' => 'M','qty' => 1),'flag' => 'G','qty' => 1),'10001' => Array('flag' => 'B','qty' => 1));
PHP
$newArray = array();
getValues($data);
function getValues($array){
global $newArray;
foreach ($array as $key => $value){
if(is_numeric($value['qty'])) {
$value['qty'] += intval($newArray[$key]['qty']);
$newArray[$key] = array('flag'=>$value['flag'],'qty'=>$value['qty']);
}
if (gettype($value) != 'array'){return;}
getValues($value);
}
}
ksort($newArray);
var_export($newArray);
Result:
array (
10001 =>
array (
'flag' => 'B',
'qty' => 2,
),
10002 =>
array (
'flag' => 'B',
'qty' => 1,
),
10003 =>
array (
'flag' => 'B',
'qty' => 2,
),
50001 =>
array (
'flag' => 'M',
'qty' => 1,
),
50002 =>
array (
'flag' => 'M',
'qty' => 1,
),
60002 =>
array (
'flag' => 'G',
'qty' => 1,
),
)
This seemed to work:
function extractArray(array $source, array &$destination, $originalIndex)
{
foreach($source as $index => $value)
{
if(is_array($value))
extractArray($value, $destination, $index);
else
$destination[$originalIndex][$index] = $value;
}
}
$test = array(
60002 => array
(
50001 => array
(
50002 => array
(
10001 => array
(
'flag' => 'B',
'qty' => 1
),
10002 => array
(
'flag' => 'B',
'qty' => 1
),
10003 => array
(
'flag' => 'B',
'qty' => 2
),
'flag' => 'M',
'qty' => 1
),
'flag' => 'M',
'qty' => 1
),
'flag' => 'G',
'qty' => 1
),
10001 => array
(
'flag' => 'B',
'qty' => 1
)
);
$new = array();
foreach($test as $index => $value)
extractArray($value, $new, $index);
var_dump($new);
die();
You can use a recursive approach to iterate over all levels of the array. For each item you check that it is an array and if it has any of the keys you want checked, add the array consisting of the found attributes.
function flattenArray($array, $keysToCheck) {
$result = array();
foreach($array as $item) {
// check if the current array item is a candidate to
// be added to the flattened array
if(is_array($item)) {
$foundAttributes = array();
foreach($item as $key=>$value) {
if(in_array($key, $keysToCheck) {
$foundAttributes[$key] = $value;
}
}
// we found at least one matching attribute
if(count($foundAttributes)) {
array_push($result, $foundAttributes);
}
// recursively go to the next level and merge the results from there
$result = array_merge($result, flattenArray($item, $keysToCheck);
}
}
return $result;
}
// usage example
$flattenedArray = flattenArray($originalArray, array('flag', 'qty'));
The above solution allows you to customise it for other type of objects, by passing different $keysToCheck arguments to the function.
If you also need the flattened array sorted, you can use usort() to achieve this.
Please pardon any syntax errors, I don't have a PHP interpreter at hand.

how to insert batch codeigniter

Ii everyone, I have an post data in array like this, I'm so confused how create the logic in controller:
POST Data:
Array
(
[nama_agenda] => blalala
[kilasan] => asdsadsadasd
[tgl_agenda] => 2014-06-01
[jam_agenda] => 13:27:30
[komisi] => Array
(
[0] => 1
[1] => 3
)
[fraksi] => Array
(
[0] => 1
[1] => 4
)
[badan] => Array
(
[0] => 1
[1] => 3
)
[anggota] => Array
(
[0] => 1
[1] => 4
)
[bagian] => Array
(
[0] => 2
[1] => 4
)
)
My question is how to insert into database, in controller? Thank's for help. I'll appreciate.
Since your structure is not well formed for insert_batch method. Your need to restructure it first. Consider this example:
$original_values = array(
'nama_agenda' => 'blalala',
'kilasan' => 'asdsadsadasd',
'tgl_agenda' => '2014-06-01',
'jam_agenda' => '13:27:30',
'komisi' => array(1, 3),
'fraksi' => array(1, 4),
'badan' => array(1, 3),
'anggota' => array(1, 4),
'bagian' => array(2, 4),
);
$new_values = array();
for($x = 0, $size = count($original_values['komisi']); $x < $size; $x++) {
foreach($original_values as $key => &$value) {
if(!is_array($value)) {
$new_values[$x][$key] = $value;
} else {
$new_values[$x][$key] = array_shift($value);
}
}
}
echo '<pre>';
print_r($new_values);
Should yield something like:
Array
(
[0] => Array
(
[nama_agenda] => blalala
[kilasan] => asdsadsadasd
[tgl_agenda] => 2014-06-01
[jam_agenda] => 13:27:30
[komisi] => 1
[fraksi] => 1
[badan] => 1
[anggota] => 1
[bagian] => 2
)
[1] => Array
(
[nama_agenda] => blalala
[kilasan] => asdsadsadasd
[tgl_agenda] => 2014-06-01
[jam_agenda] => 13:27:30
[komisi] => 3
[fraksi] => 4
[badan] => 3
[anggota] => 4
[bagian] => 4
)
)
Now you can use insert_batch() method.
$this->db->insert_batch('table_name', $new_values);
get all the data in array using $this->input->post() eg:
$bagian= $this->input->post('bagian');
and create a array()
$arr=array(
'db_table_col_1'=>$bagian,
'db_table_col_2'=>$post_data,
'db_table_col_2'=>$post_data
);
pass this array to model
$this->your_model_name->function_name($arr);
then in model create function
function_name($arg){
$this->db->insert('table_name',$arr);
}
if you want to insert multiple row then just use foreach
<?php
$arr1=array();
$arr= array(
'nama_agenda' => 'blalala',
'kilasan' => 'asdsadsadasd',
'tgl_agenda' => '2014-06-01',
'jam_agenda' => '13:27:30',
'komisi' => array
(
'0' => 1,
'1' => 3
),
'fraksi' => array
(
'0' => 1,
'1' => 4
),
'badan' => array
(
'0' => 1,
'1' => 3
),
'anggota' => array
(
'0' => 1,
'1' => 4
),
'bagian' => array
(
'0' => 2,
'1' => 4
)
);
foreach($arr as $row){
if(is_array($row)){
array_push($arr1,$row);
}
}
print_r($arr1);
and then pass this array to batch_insert
function_name($arr1){
$this->db->insert_batch('table_name',$arr1);
}
note arr1 syntax must be
$arr1 = array(
array(
'table_col1' => 'My title' ,
'table_col2' => 'My Name'
),
array(
'table_col1' => 'other title' ,
'table_col2' => 'other Name'
)
);
?>

Merge arrays (PHP)

How combine arrays in this way?
source:
Array
(
[0] => Array
(
[id] => 3
[title] => book
[tval] => 10000
)
[1] => Array
(
[id] => 3
[title] => book
[tval] => 1700
)
[3] => Array
(
[id] => 27
[title] => fruit
[tval] => 3000
)
.......
)
result:
Array
(
[0] => Array
(
[id] => 3
[title] => book
[tval] => 10000,1700
)
[1] => Array
(
[id] => 27
[title] => fruit
[tval] => 3000
)
.......
)
please help to solve this problem,
thanks!!!
sorry for bad english(
This should work:
$result = array();
foreach($array as $elem) {
$key = $elem['id'];
if (isset($result[$key])) {
$result[$key]['tval'] .= ',' . $elem['tval'];
} else {
$result[$key] = $elem;
}
}
This basically groups elements by id, concatenating tvals (separated by ,).
Simply building slightly on user576875's method:
$a = array ( 0 => array ( 'id' => 3,
'title' => 'book',
'tval' => 10000
),
1 => array ( 'id' => 3,
'title' => 'book',
'tval' => 1700
),
3 => array ( 'id' => 27,
'bcalias' => 'fruit',
'tval' => 3000
)
);
$result = array();
foreach ($a as $elem) {
$key = $elem['id'];
if (isset($result[$key])) {
$result[$key]['tval'] .= ',' . $elem['tval'];
} else {
$result[$key] = $elem;
}
}
$result = array_merge($result);
var_dump($result);
gives a result of:
array
0 =>
array
'id' => int 3
'title' => string 'book' (length=4)
'tval' => string '10000,1700' (length=10)
1 =>
array
'id' => int 27
'bcalias' => string 'fruit' (length=5)
'tval' => int 3000
The only real difference is the array_merge() to reset the keys

Categories