php insert key/value into associative array - php

I'm trying to insert a couple of new Key/Value pairs into an associative array at a specific place. From other reading I've done on SO, I'm pretty sure I have to loop through the array and insert the new values when a condition is set.
Here is the current array
array(
(int) 0 => array(
'Product' => array(
'id' => '59',
'title' => ' Blue Dress',
'Review' => array(
'id' => '7',
'product_id' => '59',
'Review' => array(
(int) 0 => array(
'average' => '3.0000'
)
)
)
)
)
(int) 1 => array(
'Product' => array(
'id' => '60',
'title' => 'Red Dress',
'Review' => array()
)
)
)
The key Review does not always have data, but when it does I want to insert a new key-value similar to the following excerpt
(int) 0 => array(
'Product' => array(
'id' => '59',
'title' => ' Blue Dress',
'Review' => array(
'id' => '7',
'product_id' => '59',
'Review' => array(
(int) 0 => array(
'average' => '3.0000'
'some_value' => '5'
)
)
)
)
)
I've tried a few things without success.
Any help is much appreciated thanks.

You can do something like this:
if(!empty($your_array[index]['Product']['Review'])){
$your_array[index]['Product']['Review']['Review'][index]['some_value'] = 'new_value';
}
In your example it could be:
if(!empty($your_array[0]['Product']['Review'])){
$your_array[0]['Product']['Review']['Review'][0]['some_value'] = 'new_value';
}
Again, you didn't mention your code. So, it's hard to figure out what you want exactly!

You should iterate through Your array and pass current value be reference:
// Notice & sign before variable
foreach ($data as &$product)
{
if ($product['Product']['Review'])
{
// or iterate through Review array
$product['Product']['Review']['Review'][0]['some_value'] = 5;
}
}

Related

CakePHP return find('all') using 'id' as array Index

So I'm trying to return a find 'all' array using the id of a 'Product' as the index key for each Product.
Typically it returns:
array(
(int) 0 => array(
'Product' => array(
'id' => '1232',
'category_id' => '330',
'name' => 'Product #1',
)
),
(int) 1 => array(
'Product' => array(
'id' => '1245',
'category_id' => '310',
'name' => 'Product #2',
)
),
(int) 2 => array(
'Product' => array(
'id' => '1248',
'category_id' => '312',
'name' => 'Product #3',
)
)
)
Whereas ideally I'd like it to return:
array(
(int) 1232 => array(
'Product' => array(
'id' => '1232',
'category_id' => '330',
'name' => 'Product #1',
)
),
(int) 1245 => array(
'Product' => array(
'id' => '1245',
'category_id' => '310',
'name' => 'Product #2',
)
),
(int) 1248 => array(
'Product' => array(
'id' => '1248',
'category_id' => '312',
'name' => 'Product #3',
)
)
)
Is this possible? And how do I go about doing it?
I have an excel spreadsheet of records that I need to match ID's to, so currently I have it iterating each spreadsheet row and performing a 'first' find to get any results, then act upon them if they do.
It works, but the recordset has grown to over 28000 and so performing one find for each has noticeable overhead.
If I can do this simply in the 'find' operation it would be great, if not, any noticeable increase in performance would be appreciated.
You can get this result as after find all :
$result = Hash::combine($data, '{n}.Product.id', '{n}.Product');
Where $data is the result of find all.
You can have your find method extended in AppModel like this
public function find($type = 'first', $query = array()) {
switch($type) {
case 'keysid':
if($results = parent::find('all', $query)){
if(isset($results[0][$this->alias]['id'])){
return Hash::combine($results, '{n}.'.$this->alias.'.id', '{n}');
}else{
return $results;
}
}
break;
default:
return parent::find($type, $query);
break;
}
}
And afterwards you can call your find method as follows:
$this->Product->find('keysid');
Then you will have a result array as you specified. However you can also do this with one line of code if you need it once. Say $products is your array from the find('all')
if($products = $this->Product->find('all')){
$alteredProducts = Hash::combine($products, '{n}.Product.id', '{n}');
}
Have a look at the Hash utility

How to copy this portion of the array to a new array in php?

I have this php array X.
X= array(
'Parent' => array(
'title' => '123',
)
)
I have this php array Y.
Y = array(
'Parent' => array(
'id' => '16',
'title' => 'T1',
),
'Children' => array(
(int) 0 => array(
'id' => '8',
'serial_no' => '1',
),
(int) 1 => array(
'id' => '9',
'serial_no' => '2',
),
(int) 2 => array(
'id' => '14',
'serial_no' => '6',
)
)
)
I want to copy the Children of array Y to the parent of array X to form array Z such that it looks like this;
Z= array(
'Parent' => array(
'title' => '123',
)
'Children' => array(
(int) 0 => array(
'serial_no' => '1'
),
(int) 1 => array(
'serial_no' => '2'
),
(int) 2 => array(
'serial_no' => '6'
)
)
)
Please note that the id key-value pair was removed from the Children of array Y.
I wrote some code of my own.
$Z = array();
$i=0;
foreach($Y as $temp)
{
$Z['Children'][$i] = $temp['Children'][$i];
unset($Z['Children'][$i]['id'];
$i++;
}
$Z['Parent']=$temp['Parent'];
Unfortunately, there is an undefined index error. How can this be done in php? Forget about my code if there are better approaches.
Actually your approach works too, but you need to iterate over sub-array:
$Z = array();
$i=0;
foreach($Y['Children'] as $temp)
{
$Z['Children'][$i] = $temp;
unset($Z['Children'][$i]['id'];
$i++;
}
or what I may do:
$Z = $X;
$Z['Children'] = array();
foreach ( $Y['Children'] as $child ) {
$Z['Children'][] = array(
'serial_no' => $child['serial_no'],
);
}
You can do like.
$Z = array();
foreach($Y['Children'] as $temp)
{
$Z['Children'][] = array('serial_no' => $temp['serial_no']);
}
$Z['Parent']=$X['Parent'];

How to transform this php associative array?

I have this php associative input array.
array(
(int) 0 => array(
'Data' => array(
'id' => '12',
'type_id' => '1',
'data_value' => '35.5000'
),
'Type' => array(
'id' => '1',
'name' => 'Temperature'
)
),
(int) 1 => array(
'Data' => array(
'id' => '11',
'type_id' => '1',
'data_value' => '33.7000'
),
'Type' => array(
'id' => '1',
'name' => 'Temperature'
)
)
I want to convert it to this output array;
array(
(int) 0 => array(
(int) 0 => array(
'v' => (int) 1
),
(int) 1 => array(
'v' => '35.5000'
)
),
(int) 1 => array(
(int) 0 => array(
'v' => (int) 2
),
(int) 1 => array(
'v' => '33.7000'
)
)
The element data_value is extracted from the input array into the output array.
The code I have written looks like this;
$data2 = array();
foreach ($InputArray as $key=>$value)
{
$data2[] = array(
array(
array('v' => $key),
array('v' => $value['Data']['data_value'])
)
);
}
Unfortunately, this code does not work. The output from this code looks like this;
array(
(int) 0 => array(
(int) 0 => array(
(int) 0 => array(
[maximum depth reached]
),
(int) 1 => array(
[maximum depth reached]
)
)
),
(int) 1 => array(
(int) 0 => array(
(int) 0 => array(
[maximum depth reached]
),
(int) 1 => array(
[maximum depth reached]
)
)
)
What did I do wrong? Why do I get the error "maximum depth reached"? How can I retrieve the desired output array? I am actually doing this in cakephp.
Thank you very much for any help.
That is one wrapping array() to many:
$data2 = array();
foreach ($InputArray as $key=>$value)
{
$data2[] = array(
array('v' => $key),
array('v' => $value['Data']['data_value'])
);
}
You can see this working here. It is good use to prepare your code in services like ideome or plnkr in order to make it easier for people to help you with debugging.
As far as I know, the problem is related to a setting for PHP http://www.hardened-php.net/suhosin/configuration.html#suhosin.executor.max_depth . Could you check with your hosting provider?

Push array inside another array

I have a site develop in php and I have a function where I want to create an array inside other array.
My query are this (i'm using cakephp but in this case is only a problem of array don't tell me to use contain or something like that from cakephp because is a large query and I need to construct my query and my array in this mode)
My array $product_ingredient contain some value.
foreach ($product_ingredient as $key) {
$ingredient_level1 = $this->ProductIngredientVersion->query('SELECT * FROM ingredients_ingredients
WHERE ingredients_ingredients.ingredient_id = :ingredient_id
AND ingredients_ingredients.product_id = :id
AND ingredients_ingredients.version_id = :version_id
AND ingredients_ingredients.level = 1', array('id' => $id, 'ingredient_id' => $key['products_ingredients']['ingredient_id'], 'version_id' => $key['products_ingredients']['version_id']));
foreach($ingredient_level1 as $key2){
$ingredient_level2 = array($this->ProductIngredientVersion->query('SELECT * FROM ingredients_ingredients
WHERE ingredients_ingredients.ingredient_id = :ingredient_id
AND ingredients_ingredients.product_id = :id
AND ingredients_ingredients.version_id = :version_id
AND ingredients_ingredients.level = 2', array('id' => $id, 'ingredient_id' => $key2['ingredients_ingredients']['ingredient2_id'], 'version_id' => $key2['ingredients_ingredients']['version_id'])));
array_push($ingredient_level1, $ingredient_level2);
}
array_push($ingredient_ingredient, $ingredient_level1);
}
The result is that:
array(
(int) 0 => array(
(int) 0 => array(
'ingredients_ingredients' => array(
'id' => '34',
'level' => '1'
)
),
(int) 1 => array(
(int) 0 => array(
(int) 0 => array(
'ingredients_ingredients' => array(
'id' => '35',
'level' => '2'
)
)
)
)
)
But I would like this result
array(
(int) 0 => array(
(int) 0 => array(
'ingredients_ingredients' => array(
'id' => '34',
'level' => '1',
array(
'ingredients_ingredients' => array(
'id' => '35',
'level' => '2'
)
)
)
)
How can I solve?
Replace
array_push($ingredient_ingredient, $ingredient_level1);
by
array_push(
$ingredient_ingredient[0][0]['ingredients_ingredients'],
$ingredient_level1
);
This pushes the array to the appropriate cascade level. However it is very likely that this is the most efficient way, if you're unable to modify SQL or array structure elsewhere.

PHP - structure multidimensional array depending on values

I have an array:
$initialarray = array(
0 = array(
'unit' => 1,
'class' => 1,
'value' => 'string1'
),
1 = array(
'unit' => 1,
'class' => 2,
'value' => 'string2'
),
2 = array(
'unit' => 1,
'class' => 2,
'value' => 'string3'
),
3 = array(
'unit' => 2,
'class' => 1,
'value' => 'string4'
)
4 = array(
'unit' => 2,
'class' => 2,
'value' => 'string5'
)
);
What would be the best way to structure it (to group the resulting sub-arrays) depending first on the 'unit' field's values, and then depending on the 'class' field's values, like so:
$resultarray = array(
// array of all the sub-arrays of 'unit' = 1
$unit[1] = array(
// array of all the sub-arrays of 'unit' = 1 and 'class' = 1
$class[1] = array(
0 = array(
'unit' => 1,
'class' => 1,
'value' => 'string1'
)
)
// array of all the sub-arrays of 'unit' = 1 and 'class' = 2
$class[2] = array(
0 = array(
'unit' => 1,
'class' => 2,
'value' => 'string2'
),
1 = array(
'unit' => 1,
'class' => 2,
'value' => 'string3'
)
)
)
// array of all the sub-arrays of 'unit' = 2
$unit[2] = array(
// array of all the sub-arrays of 'unit' = 2 and 'class' = 1
$class[1] = array(
0 = array(
'unit' => 2,
'class' => 1,
'value' => 'string4'
)
)
// array of all the sub-arrays of 'unit' = 2 and 'class' = 2
$class[2] = array(
0 = array(
'unit' => 2,
'class' => 2,
'value' => 'string5'
)
)
)
)
I have asked a similar question here and got a working answer for only one iteration, i.e. for only structuring the array by one of the fields. But I could not make the same solution work for multiple iterations, i.e. for more than one field.
Also, is there a solution to structure a multidimensional array depending on more than two fields?
I think it's not a way of asking the question. It is very simple , you can do this by playing with arrays,keys and etc.... So first you should try hard for the problem. After If you have any problem in the middle of your tries then you can ask that here. I have solved your problem here is the complete code , but next time please do some work and then only post the problem. Never ask for the code.
foreach ($initialarray as $key1=>$val1)
{
foreach ($val1 as $key2=>$val2)
{
if($key2=='unit')
{
$num=$val2;
if($val2!=$num)
$testarr['unit'.$val2]=array();
}
if($key2=='class')
{
$testarr['unit'.$num]['class'.$val2][]=$val1;
}
}
}
print_r($testarr);
I must offer a better way for you and future researchers...
You only need one loop, and you merely need to nominate the result array's key values before using [] to "push" new data into the deepest subarray.
*there is absolutely no need for any condition statements or a second loop.
Code: (Demo)
$initialarray = [
['unit' => 1, 'class' => 1, 'value' => 'string1'],
['unit' => 1, 'class' => 2, 'value' => 'string2'],
['unit' => 1, 'class' => 2, 'value' => 'string3'],
['unit' => 2, 'class' => 1, 'value' => 'string4'],
['unit' => 2, 'class' => 2, 'value' => 'string5']
];
foreach ($initialarray as $row) {
$result[$row['unit']][$row['class']][] = $row;
}
var_export($result);
Output:
array (
1 =>
array (
1 =>
array (
0 =>
array (
'unit' => 1,
'class' => 1,
'value' => 'string1',
),
),
2 =>
array (
0 =>
array (
'unit' => 1,
'class' => 2,
'value' => 'string2',
),
1 =>
array (
'unit' => 1,
'class' => 2,
'value' => 'string3',
),
),
),
2 =>
array (
1 =>
array (
0 =>
array (
'unit' => 2,
'class' => 1,
'value' => 'string4',
),
),
2 =>
array (
0 =>
array (
'unit' => 2,
'class' => 2,
'value' => 'string5',
),
),
),
)
If I may express myself in the following manner: I only see the front-end of your problem and know nothing about its back-end, e.g. "Where does the data come from?", "How is it collected and stored", etc. so my answer might not be a real help but still I'll give my "tuppence".
If you can store all that data in a relational database (in form of table(s)) it would be much more easier and faster(!) to select the needed data from the database instead of rearranging arrays, which will take some more time in comparison.
Just as an example you might then select (and store it into an array) all items which have unit = '1' and / or all items which have class = '2'. That would make life much more easier IMHO, than having all the data in a multidimensional array and then try to sort it / rearrange it. Especially if you do that based on more than one property.

Categories