add new element to an N-level Multidimentional array in PHP - php

I have an N-level Multidimentional array like this:
Array
(
[0] => Array
(
[id] => 7_cat
[text] => cat1
[children] => Array
(
[0] => Array
(
[id] => 9_cat
[text] => cat3
)
)
)
[1] => Array
(
[id] => 8_cat
[text] => cat2
)
[2] => Array
(
[id] => 13_cat
[text] => cat4
)
)
and i have an array of index like this:
Array
(
[0] => 0
[1] => children
[2] => 0
[3] => id
)
so i want to add a new element in first array in these depth. in this example i want to add a new element in $firstarray[0]['children'][0]['id'].
How can i do it?
thanks alot

Do Like this
Here $oldArray is your first array
$indexArray=Array
(
[0] => 0
[1] => children
[2] => 0
[3] => id
);
$indexForold=[];
foreach($indexArray as $indx){
$indexForold=$indexForold[$indx];
}
$oldArray[$indexForold]=$myVal;

The solution is, while traversing the array use reference to keep a reference to the current array element.
Here $nArr is your n-dimensional array and $indexArr is your index array.
And don't forget to replace <YOUR_VALUE> with your desired value.
So your code should be like this:
$arrLength = count($indexArr);
$tmpArr = null;
$i = 0;
for(; $i < $arrLength - 1; ++$i){
if($tmpArr == null){
$tmpArr = &$nArr[$indexArr[$i]];
}else{
$tmpArr = &$tmpArr[$indexArr[$i]];
}
}
$tmpArr[$indexArr[$i]] = <YOUR_VALUE>;
// now display the n-dimensional array
echo "<pre>";
print_r($nArr);
echo "</pre>";

You can try something like this...
$array = [
[
'id' => '7_cat',
'text' => 'cat1',
'children' => [
[
'id' => '9_cat',
'text' => 'cat3'
]
]
],
[
'id' => '8_cat',
'text' => 'cat2'
],
[
'id' => '13_cat',
'text' => 'cat4'
]
];
$multIndexValue = function (array $indexList, array $searchArray) {
$result = $searchArray;
foreach ($indexList as $index) {
$result = $result[$index];
}
return $result;
};
$search = [0, 'children', 0, 'id'];
$result = $multIndexValue($search, $array); // string(5) "9_cat"

Related

PHP - How To Grouping if value same in array

This my array example
Array
(
[0] => Array ( [_id] => 5f76b1788ee23077dccd1a2c [product] => Array ( [0] => Array ( [_id] => 5d0391a4a72ffe76b8fcc610 ) ) [count] => 1 )
[1] => Array ( [_id] => 5f76b6288ee2300700cd1a3a [product] => Array ( [0] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) ) [count] => 1 )
[2] => Array ( [_id] => 5f76d2488ee23083d3cd1a4a [product] => Array ( [0] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) ) [count] => 1)
)
And i want to group if product value same, like this,
Array
(
[0] => Array ( [_id] => 5f76b1788ee23077dccd1a2c [product] => Array ( [0] => Array ( [_id] => 5d0391a4a72ffe76b8fcc610 ) ) [count] => 1 )
[1] => Array ( [_id] => 5f76b6288ee2300700cd1a3a [product] => Array ( [0] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) ) [count] => 2 )
)
It makes no sense to retain the first level ids since you are arbitrarily trashing some of the first level ids (damaging the relationships) during the merging process.
Instead I recommend that you only isolate the data that is accurately related.
If this output does not serve your needs, then I'll ask for further question clarification.
By assigning temporary keys to your output array, the output array also acts as a lookup array by which you can swiftly check for uniqueness. The "null coalescing operator" (??) sets a fallback value of 0 when an id is encountered for the first time -- this prevents generating any warnings regarding undeclared keys.
Code: (Demo)
$array = [
['_id' => '5f76b1788ee23077dccd1a2c', 'product' => ['_id'=>'5d0391a4a72ffe76b8fcc610'], 'count'=> 1],
['_id' => '5f76b6288ee2300700cd1a3a', 'product' => ['_id'=>'5d0391b6a72ffe76b8fcc611'], 'count'=> 1],
['_id' => '5f76d2488ee23083d3cd1a4a', 'product' => ['_id'=>'5d0391b6a72ffe76b8fcc611'], 'count'=> 1]
];
$productCounts = [];
foreach ($array as $item) {
$productId = $item['product']['_id'];
$productCounts[$productId] = ($productCounts[$productId] ?? 0) + $item['count'];
}
var_export($productCounts);
Output:
array (
'5d0391a4a72ffe76b8fcc610' => 1,
'5d0391b6a72ffe76b8fcc611' => 2,
)
If you insist of the desired output in your question, then it can be as simple and efficient as this...
Code: (Demo)
$result = [];
foreach ($array as $item) {
$productId = $item['product']['_id'];
if (!isset($result[$productId])) {
$result[$productId] = $item;
} else {
$result[$productId]['count'] += $item['count'];
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'_id' => '5f76b1788ee23077dccd1a2c',
'product' =>
array (
'_id' => '5d0391a4a72ffe76b8fcc610',
),
'count' => 1,
),
1 =>
array (
'_id' => '5f76b6288ee2300700cd1a3a',
'product' =>
array (
'_id' => '5d0391b6a72ffe76b8fcc611',
),
'count' => 2,
),
)
You can try the below code it will work for you :-)
<?php
$Myarray = array(['_id'=> '5f76b1788ee23077dccd1a2c', 'product'=> ['_id'=>'5d0391a4a72ffe76b8fcc610'] ,'count'=> 1 ],
['_id'=> '5f76b6288ee2300700cd1a3a', 'product'=> ['_id'=>'5d0391b6a72ffe76b8fcc611'] ,'count'=> 1 ],
['_id'=> '5f76d2488ee23083d3cd1a4a', 'product'=> ['_id'=>'5d0391b6a72ffe76b8fcc611'] ,'count'=> 1 ]
);
$user_array = [];
$temp_array = [];
foreach($Myarray as $temp)
{
$found = array_search($temp['product']['_id'], $temp_array);
if($found !== false)
{
$i = 0;
foreach($user_array as $temp1)
{
if($temp1['product']['_id'] == $temp['product']['_id'])
{
$sum = $temp1['count'] + 1;
$user_array[$i]['count'] = $sum;
}
$i++;
}
}
else
{
array_push($user_array,$temp);
array_push($temp_array,$temp['product']['_id']);
}
}
print_r($user_array);
?>
This will produce below Output
Array ( [0] => Array ( [_id] => 5f76b1788ee23077dccd1a2c [product] => Array ( [_id] => 5d0391a4a72ffe76b8fcc610 ) [count] => 1 ) [1] => Array ( [_id] => 5f76b6288ee2300700cd1a3a [product] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) [count] => 2 ) )

How to loop multi dimensional array to get values

I have this multi-dimensional array and I'm trying to convert it into array given below
Array
(
[id] => Array
(
[0] => 1
[1] => 3
)
[team_id] => Array
(
[0] => 654868479
[1] => 463733228
)
[seed] => Array
(
[0] => 1
[1] => 2
)
)
I want following result
Array
(
[0] => Array
(
[id] => 1
[team_id] => 654868479
[seed] => 1
)
[1] => Array
(
[id] => 3
[team_id] => 463733228
[seed] => 3
)
)
Here is what I have achieved so far. I actually want $seeded[] array is the same format as it is required to submit update_batch. Which will ultimately update database records.
$seeds = $this->input->post();
$i=0;
foreach ($seeds as $key => $value){
if(!empty($key) && !empty($value)){
for($i=0; $i=5; $i++) {
$seeded[] = array(
'id' => (id go here),
'tournament_id' => $tournament_id,
'stage_id' => $stage_id,
'seed_id' => (seed go here),
'team_name' => (team_id go here),
);
}
$this->db->update_batch('tournament_seed', $seeded, 'id');
}
}
Iterate the array and convert it using below code.
$seeded= array();
for($i =0; $i < count($seeds['id']); $i++){
$tempArr['id'] = $seeds['id'][$i];
$tempArr['team_id'] = $seeds['team_id'][$i];
$tempArr['seed'] = $seeds['seed'][$i];
$seeded[] = $tempArr;
}
I've written a function that will allow you to transform any array of similar structure to what you have above, to an array of the form you are looking for.
You can build your array in this way:
$arr = [
'id' => [1, 3],
'team_id' => [654868479, 463733228],
'seed' => [1, 2],
];
function array_flatten($arr) {
$res = [];
foreach($arr as $id => $valuesArray) {
foreach($valuesArray as $index => $value)
$res[$index][$id] = $value;
}
return $res;
}
print_r(array_flatten($arr));
Hope this helps,

How to use array_column or foreach to get result

This is my array,with the use of array_column or any loop I want to replace keys as value of next element .I don't want to change parent array index
Array
(
[0] => Array
(
[id] => 11
[total] => 100000
[content] => abc
)
[1] => Array
(
[id] => 22
[total] => 200000
[content] => def
)
)
This is the array I would like to have.
Array
(
[0] => Array
(
[11] => 100000
[content] => abc
)
[1] => Array
(
[22] => 200000
[content] => def
)
)
It is very simple Try this:-
$array = array(
'0'=>array('id'=> 10,'total'=> 100000,'content' => 'abc'),
'1'=>array('id'=> 11,'total'=> 200000,'content' => 'def')
);
foreach($array as $key => $val){
$array[$key][$val['id']] = $val['total'];
unset($array[$key]['total']);
unset($array[$key]['id']);
}
echo "<pre>"; print_r($array); die; // print array data here
Hope it helps!
Using 'foreach' to modify existing array works perfect, but 'array_walk' is just more expressive, because it was designed for this task.
<?php
$array = [
[
'id' => 11,
'total' => 10000,
'content' => 'abc'
],
[
'id' => 22,
'total' => 200000,
'content' => 'def'
]
];
array_walk($array, function(&$row) {
$row[$row['id']] = $row['total'];
unset($row['id'], $row['total']);
});
var_dump($array);
It can be done with array_map function
$new = array_map(function($x) {
return [ $x['id']=> $x['total'], 'content' => $x['content']]; },
$array);
demo

Array reduce with associative array

I have an array like this
$filter_array = Array
(
[0] => Array
(
[fv_id] => 1
[fv_value] => Red
[filter_id] => 1
[filter_name] => Color
)
[1] => Array
(
[fv_id] => 2
[fv_value] => Blue
[filter_id] => 1
[filter_name] => Color
)
)
I would like to reduce the array by having filter_name and filter_id on top of array which is similar for all arrays.
$newArray = array_reduce($filter_array,function($carry,$item){
$allFilterValues[] = array(
'fv_id' => $item['fv_id'],
'fv_value' => $item['fv_value'],
);
$formated_array = array(
'filter_id' => $item['filter_id'],
'filter_name' => $item['filter_name'],
'filter_values' => $allFilterValues
);
return $formated_array;
});
But I am just getting the last array iterations value on filter_values
Array
(
[filter_id] => 1
[filter_name] => Color
[filter_values] => Array
(
[0] => Array
(
[fv_id] => 2
[fv_value] => Blue
)
)
)
But I want the array be like this.
Array
(
[filter_id] => 1
[filter_name] => Color
[filter_values] => Array
(
[0] => Array
(
[fv_id] => 1
[fv_value] => Red
),
[1] => Array
(
[fv_id] => 2
[fv_value] => Blue
)
)
)
On each iteration of array_reduce callback function must return current $carry value:
$newArray = array_reduce($filter_array,function($carry,$item){
// create key so as to distinct values from each other
$key = $item['filter_id'] . '-' . $item['filter_name'];
// check if created key exists in `$carry`,
// if not - we init it with some data
if (empty($carry[$key])) {
$carry[$key] = [
'filter_id' => $item['filter_id'],
'filter_name' => $item['filter_name'],
'filter_values' => []
];
}
// add values to `filter_values`
$carry[$key]['filter_values'][] = [
'fv_id' => $item['fv_id'],
'fv_value' => $item['fv_value'],
];
return $carry;
}, []);
// if you want to reindex `$newArray` from 0:
$newArray = array_values($newArray);
Update: if and only if in your $filter_array values of 'filter_id' and 'filter_name' are always the same you can simplify your code:
$newArray = [];
$first = true;
foreach ($filter_array as $item) {
if ($first) {
$first = false;
$newArray = [
'filter_id' => $item['filter_id'],
'filter_value' => $item['filter_name'],
'filter_values' => []
];
}
$newArray['filter_values'][] = [
'fv_id' => $item['fv_id'],
'fv_value' => $item['fv_value'],
];
}
echo'<pre>',print_r($newArray),'</pre>';

How to combine each subarray of subarrays and store them as comma separated strings?

I need to join all subarray Name values in single subarray.
Given input format:
Array
(
[0] => Array
(
[0] => Array
(
[Name] => kumar
)
[1] => Array
(
[Name] => siva
)
)
[1] => Array
(
[0] => Array
(
[Name] => Arun
)
[1] => Array
(
[Name] => Prem
)
)
)
required output format
Array
(
[0] => Array
(
[0] => Array
(
[Name] => kumar, siva
)
)
[1] => Array
(
[0] => Array
(
[Name] => Arun, Prem
)
)
)
My coding attempt:
$final = array();
foreach ($NameArray as $row) {
foreach ($row as $rows) {
$final[] = $rows['Name'];
}
}
print_r($final);
It shows each separate. I need each subarray to be a single array name with comma format.
You can do something like this:
foreach($a as $k1=>$ar1){
$text = '';
foreach($ar1 as $t){
$text .= "{$t['Name']}, ";
}
unset($a[$k1]);
$a[$k1][0]['Name'] = substr($text,0,-2);
}
var_dump($a);
Output:
array (size=2)
0 =>
array (size=1)
0 =>
array (size=1)
'Name' => string 'kumar, siva' (length=10)
1 =>
array (size=1)
0 =>
array (size=1)
'Name' => string 'Arun, Prem' (length=9)
This can be solved succinctly with one loop and the implosion of the columnar values in each subarray.
Code (Demo)
$a = [
[['Name' => 'kumar'],['Name' => 'siva']],
[['Name' => 'Arun'],['Name' => 'Prem']]
];
foreach ($a as $i => $group) {
$result[$i][] = ['Name' => implode(', ', array_column($group, 'Name'))];
}
var_export($result);
Output:
array (
0 =>
array (
0 =>
array (
'Name' => 'kumar, siva',
),
),
1 =>
array (
0 =>
array (
'Name' => 'Arun, Prem',
),
),
)

Categories