Add array elements to associative array - php

I am unable to find a way to take the elements of an array (product IDs) and add them to a particular key of an associative array ($choices['id]) so that it creates as many instances of that array ($choices[ ]) as there are elements in $id.
I want the final version of $choices[ ] to include as many arrays as there are elements in $id[ ].
After that I want to repeat this process for part_numbers & quantity.
// Create $choices array with keys only
$choices = array(
'id' => '',
'part_number' => '',
'quantity' => '',
);
// Insert $id array values into 'id' key of $choices[]
$id = array('181', '33', '34');

If I'm understanding your question correctly, you mean something like this?
$choices = array();
$id = array('181', '33', '34');
foreach($id as $element)
{
$choices[] = array(
'id' => $element,
'part_number' => '',
'quantity' => '',
);
}
echo "<pre>";
print_r($choices);
echo "</pre>";
Output:
Array (
[0] => Array
(
[id] => 181
[part_number] =>
[quantity] =>
)
[1] => Array
(
[id] => 33
[part_number] =>
[quantity] =>
)
[2] => Array
(
[id] => 34
[part_number] =>
[quantity] =>
)
)
Edit:
A more general solution would be as follows:
$choices = array();
$values = array('sku-123', 'sku-132', 'sku-1323');
foreach($values as $i => $value){
if(array_key_exists($i, $choices))
{
$choices[$i]['part_number'] = $value;
}
else
{
$choices[] = array(
'id' => '',
'part_number' => $value,
'quantity' => '',
);
}
}
This can be used for array creation and insertion, hence the if/else block.

Related

shift multidimentional array to single array

I want to remove key 0 from parent array and set child array as parent.
Here I will get single value so one array is ok for me.
My current array looks like this
Array
(
[0] => Array
(
[id] => 3
[api_key] => acount266
[auth_domain] => Tester26
[database_url] => vcc.test.acc+27#gmail.com
[project_id] => 12345
[storage_bucket] =>
[secret_key_path] =>
[fcm_server_key] => 1
[messaging_sender_id] => 0
[key_phrase] =>
[disable] => 0
[created] =>
[updated] =>
)
)
I want it like below. expected result
Array
(
[id] => 3
[api_key] => acount266
[auth_domain] => Tester26
[database_url] => vcc.test.acc+27#gmail.com
[project_id] => 12345
[storage_bucket] =>
[secret_key_path] =>
[fcm_server_key] => 1
[messaging_sender_id] => 0
[key_phrase] =>
[disable] => 0
[created] =>
[updated] =>
)
For this I tried like below but no success.
$new = array();
foreach ($data as $v){
$new = array_merge($new , array_values($v)) ;
}
but in my code it's removed key e.g id,api_key, etc....
I need key name also in my new array. please suggest
Remove the array_values
Solution
<?php
$test = array(
array
(
'id' => 3,
'api_key' => 'acount266'
)
);
$new = array();
foreach($test as $v){
$new = array_merge($new, $v);
}
var_dump($new);
Result
array(2) {
["id"]=>
int(3)
["api_key"]=>
string(9) "acount266"
}
According to documentation of PHP as mentioned
reset() function returns the value of the first array element, or
FALSE if the array is empty.
$array = array(
array(
'id' => 3,
'api_key' => 'acount266',
'auth_domain' => 'Tester26',
'database_url' => 'vcc.test.acc+27#gmail.com',
'project_id' => '12345',
'storage_bucket' => '',
'secret_key_path' => '',
'fcm_server_key' => 1,
'messaging_sender_id' => 0,
'key_phrase' => '',
'disable' => 0,
'created' => '',
'updated' => ''
)
);
print_r(reset($test));
I tried this:
$arr = array();
foreach ($examples as $example) {
foreach ($example as $e) {
array_push($arr, $e);
}
}
Don't overcomplicate this, reassigning the first element to the parent array is quick and easy:
<?php
$array =
array (
0 =>
array (
'first' => 'Michael',
'last' => 'Thompson'
)
);
$array = $array[0];
var_export($array);
Output:
array (
'first' => 'Michael',
'last' => 'Thompson',
)
Or:
$array = array_shift($array);

How to merge selected elements of an array in PHP?

I have an array as
$array = array (
0 => array( 'name' => 'zero'),
1 => array( 'name' => 'one'),
2 => array( 'name' => 'two'),
3 => array( 'name' => 'three'),
4 => array( 'name' => 'four'),
5 => array( 'name' => 'five'),
6 => array( 'name' => 'six'),
);
and I need to merge some elements according to a pattern
$pattern = array(
array('from'=>1, 'to'=>2, 'note'=>'something'),
array('from'=>3, 'to'=>5, 'note'=>'something'),
array('from'=>6, 'to'=>6, 'note'=>'something'),
);
How can I merge the elements to get an array of
$ result = array(
['0'] => array('name'=>'zero'),
['1,2'] => array('name'=>'one+two', 'note'=>'something'),
['3,4,5'] => array('name'=>'three+four+five', 'note'=>'something'),
['6'] => array('name'=>'six', 'note'=>'something'),
);
I understand that I should iterate one array in a loop and check the other one for the corresponding element to create a new array, but which one should I iterate?
If the array keys aren’t actually important, then I’d go about it like this:
$result = $processed = [];
foreach($pattern as $p) { // loop over the patterns
$temp = [];
for($i = $p['from']; $i <= $p['to']; ++$i) { // loop over from -> to
$temp[] = $array[$i]['name']; // collect names of those items
$processed[] = $i; // store index of item as an already processed one
}
$result[] = ['name' => implode('+', $temp), 'note' => $p['note']];
}
$temp = [];
foreach($array as $key => $item) {
if(!in_array($key, $processed)) { // if index is not in list of already processed items
$temp[] = $item['name'];
}
}
array_unshift($result, ['name' => implode('+', $temp)]); // add to front of result
That will get you a result of the form
Array
(
[0] => Array
(
[name] => zero
)
[1] => Array
(
[name] => one+two
[note] => something
)
[2] => Array
(
[name] => three+four+five
[note] => something
)
[3] => Array
(
[name] => six
[note] => something
)
)

Array Multisort with a multidirectional array [duplicate]

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 7 years ago.
This one is baffling me at the moment, and I'm a little confused as to what it is doing.
So I have a multi directional array:
$h_info[69993] = array('price' => '1.00', 'url' => 'url', 'rating' => '4');
$h_info[85398] = array('price' => '3.00', 'url' => 'url', 'rating' => '2');
$h_info[34394] = array('price' => '9.00', 'url' => 'url', 'rating' => '0');
Now I have the following while loop
foreach ($h_info as $row) {
foreach ($row as $key => $value){
${$key}[] = $value; //Creates $price, $url... arrays.
}
}
array_multisort($price, SORT_ASC, $h_info);
Now this works, but it removes the $h_info id from the array and outputs
Array
(
[0] => Array
(
[price] => 39
[url] => url,
[rating] => 4.5
)
...
But i need the ID to stay - when I do this:
foreach ($h_info as $row => $id) {
foreach ($row as $key => $value){
${$key}[] = $value; //Creates $price, $url... arrays.
}
}
array_multisort($price, SORT_ASC, $h_info);
The sort no longer works, but outputs the array correctly:
Array
(
[69993] => Array
(
[price] => 39
[url] => url,
[rating] => 4.5
)
...
Try this
$h_info[69993] = array('price' => '1.00', 'url' => 'url', 'rating' => '4');
$h_info[85398] = array('price' => '3.00', 'url' => 'url', 'rating' => '2');
$h_info[34394] = array('price' => '9.00', 'url' => 'url', 'rating' => '0');
//intitalize array
$result = array(); // or $result = [];
//add your main key into "key" parameter of array
array_walk($h_info, function (&$value,$key) use (&$result) {
$arr_info = $value;
$arr_info['key'] = $key;
$result[] = $arr_info;
});
//sort in ascending order by price
usort($result, function($a, $b) {
if($a['price']==$b['price']) return 0;
return $b['price'] < $a['price']?1:-1; // return $a['price'] < $b['price']?1:-1;(note : if you need it in descending order)
});
echo "<pre>";
print_r($result);
?>
and you will get result like this
Array
(
[0] => Array
(
[price] => 1.00
[url] => url
[rating] => 4
[key] => 69993
)
[1] => Array
(
[price] => 3.00
[url] => url
[rating] => 2
[key] => 85398
)
[2] => Array
(
[price] => 9.00
[url] => url
[rating] => 0
[key] => 34394
)
)
in ascending order by price
if you need to know more information abouta array_walk() and usort() please check this links :
http://php.net/manual/en/function.array-walk.php
http://php.net/manual/en/function.usort.php

Group array rows by one column and only create a subarray from another column if more than one value

How can I group row data from a two-dimensional array and only create a subarray of another column if the respective group contains more than one value?
In other words, I need to group rows by id and conditionally restructure an array of arrays to have a variable depth of either 2 or 3 levels.
Input:
[
['id' => 567, 'value' => 780],
['id' => 676, 'value' => 743],
['id' => 676, 'value' => 721],
['id' => 234, 'value' => 766],
['id' => 234, 'value' => 680]
]
Desired output:
[
['id' => 567, 'value' => 780],
['id' => 676, 'value' => [743, 721]],
['id' => 234, 'value' => [766, 680]]
]
Are you sure you want to have the value as an integer when there is one value and an array when there are more?
<?php
$array = array(
array('id' => 567, 'value' => 780),
array('id' => 676, 'value' => 743),
array('id' => 676, 'value' => 721),
array('id' => 234, 'value' => 766),
array('id' => 234, 'value' => 680)
);
foreach ($array as $item) {
$result[$item['id']][] = $item['value'];
}
foreach ($result as $id => $value) {
if (count($value) > 1) {
$output[] = array(
'id' => $id,
'value' => $value
);
} else {
$output[] = array(
'id' => $id,
'value' => $value[0]
);
}
}
echo '<pre>';
print_r($output);
echo '</pre>';
?>
If not
<?php
$array = array(
array('id' => 567, 'value' => 780),
array('id' => 676, 'value' => 743),
array('id' => 676, 'value' => 721),
array('id' => 234, 'value' => 766),
array('id' => 234, 'value' => 680)
);
foreach ($array as $item) {
$result[$item['id']][] = $item['value'];
}
foreach ($result as $id => $value) {
$output[] = array(
'id' => $id,
'value' => $value
);
}
echo '<pre>';
print_r($output);
echo '</pre>';
?>
try this one
$array['key1'] = array(
0=>array('id'=>567, 'value'=>780),
1=>array('id'=>676, 'value'=>743),
2=>array('id'=>676, 'value'=>721),
3=>array('id'=>234, 'value'=>766),
4=>array('id'=>234, 'value'=>780)
);
foreach($array['key1'] as $subarray){
$group_id = $subarray['id'];
if(!isset($return[$group_id]))
$return[$group_id] = $subarray;
else{
if(is_array($return[$group_id]['value']))
array_push($return[$group_id]['value'], $subarray['value']);
else
$return[$group_id]['value'] = array($subarray['value'], $return[$group_id]['value']);
}
}
// reset grouping keys into 0,1...
$return = array_values($return);
print_r($return);
There, all the work done for you. How easy is that!
//create the array as you have now
$array[0] = ['id'=>567, 'value'=>780];
$array[1] = ['id'=>676, 'value'=>743];
$array[2] = ['id'=>676, 'value'=>721];
$array[3] = ['id'=>234, 'value'=>766];
$array[4] = ['id'=>234, 'value'=>780];
print_r($array);
print chr(10).chr(10);
//create a new array with the values combined on key
$concat = array();
foreach($array as $val) {
$i = $val['id'];
$v = $val['value'];
if (!is_array($concat[$i]))
$concat[$i] = array();
$concat[$i][] = $v;
}
print_r($concat);
print chr(10).chr(10);
//create a new array to show the data as you want.
$newarray = array();
foreach($concat as $key=>$val) {
$t = array();
$t['id'] = $key;
if (count($val)==1)
$t['value'] = $val[0];
else {
$t['value'] = array();
foreach($val as $v)
$t['value'][] = $v;
}
$newarray[] = $t;
}
print_r($newarray);
print chr(10).chr(10);
Result:
Array
(
[0] => Array
(
[id] => 567
[value] => 780
)
[1] => Array
(
[id] => 676
[value] => 743
)
[2] => Array
(
[id] => 676
[value] => 721
)
[3] => Array
(
[id] => 234
[value] => 766
)
[4] => Array
(
[id] => 234
[value] => 780
)
)
Array
(
[567] => Array
(
[0] => 780
)
[676] => Array
(
[0] => 743
[1] => 721
)
[234] => Array
(
[0] => 766
[1] => 780
)
)
Array
(
[0] => Array
(
[id] => 567
[value] => 780
)
[1] => Array
(
[id] => 676
[value] => Array
(
[0] => 743
[1] => 721
)
)
[2] => Array
(
[id] => 234
[value] => Array
(
[0] => 766
[1] => 780
)
)
)
<?php
$arr['key1'] = array(
array(
'id' => 567,
'value' => 780,
),
array(
'id' => 676,
'value' => 743,
),
array(
'id' => 676,
'value' => 721,
),
array(
'id' => 234,
'value' => 766,
),
array(
'id' => 234,
'value' => 780,
),
);
/* handle element merge */
function array_internal_merge_func($a, $b) {
if ( is_array($a['value']) )
$a['value'][] = $b['value'];
else
$a['value'] = array($a['value'], $b['value']);
return $a;
}
/* handle array merge */
function array_internal_merge($array, $key, $merge_func) {
$hashed = array();
$result = array();
foreach ( $array as $idx => $ele )
$hashed[$ele[$key]][] = $idx;
foreach ( $hashed as $key => $idxies ) {
reset($idxies);
$idx0 = current($idxies);
$result[$idx0] = $array[$idx0];
while ( $idx = next($idxies) )
$result[$idx0] = $merge_func($result[$idx0], $array[$idx]);
}
return $result;
}
print_r(array_internal_merge($arr['key1'], 'id', 'array_internal_merge_func'));
This task can certainly be done concisely with one loop.
Use id column values as temporary first level keys. This makes identifying duplicates most efficient and easy.
While iterating:
if a row's id is new to the result array, then push the whole row (in its original, flat structure) into the result array; or
if a row's id was encountered before, then cast the stored row's value element as an array before pushing the current row's value into that subarray.
If you do not want your result to have id values as the first level keys, then call array_values() to re-index the result.
The special action done implemented below is that when casting a scalar or null data type to an array, the value becomes the lone element of the newly formed array. If an array is explicitly cast as an array, then there is no effect on the data structure at all. This is why (array) can be unconditionally applied in the else branch.
Code: (Demo)
foreach ($array as $row) {
if (!isset($result[$row['id']])) {
$result[$row['id']] = $row;
} else {
$result[$row['id']]['value'] = array_merge(
(array) $result[$row['id']]['value'],
[$row['value']]
);
}
}
var_export(array_values($result));
An alternative without array_merge(): (Demo)
foreach ($array as $row) {
if (!isset($result[$row['id']])) {
$result[$row['id']] = $row;
} else {
$result[$row['id']]['value'] = (array) $result[$row['id']]['value'];
$result[$row['id']]['value'][] = $row['value'];
}
}
var_export(array_values($result));
An alternative with array_reduce(): (Demo)
var_export(
array_values(
array_reduce(
$array,
function($result, $row) {
if (!isset($result[$row['id']])) {
$result[$row['id']] = $row;
} else {
$result[$row['id']]['value'] = (array) $result[$row['id']]['value'];
$result[$row['id']]['value'][] = $row['value'];
}
return $result;
}
)
)
);

Which PHP Array function should I use?

I have two arrays:
Array
(
[0] => Array
(
[id] => 1
[type] => field
[remote_name] => Title
[my_name] => title
[default_value] => http%3A%2F%2Ftest.com
)
[1] => Array
(
[id] => 2
[type] => field
[remote_name] => BookType
[my_name] => book-type
[default_value] =>
)
[2] => Array
(
[id] => 3
[type] => value
[remote_name] => dvd-disc
[my_name] => dvd
[default_value] =>
)
)
Array
(
[title] => Test
[book-type] => dvd
)
I need to take each key in the second array, match it with the my_name value in the first array and replace it with the corresponding remote_name value of the first array while preserving the value of the second array.
There's got to be some carrayzy function to help!
EDIT: There will also be a few cases that the value of the second array will need to be replaced by the value of the first array's remote_name where the value of the second array matches the value of the first array's my_name. How can I achieve this?
EG: book-type => dvd should turn into BookType => dvd-disc
Like so?:
$first = array(
array(
'id' => 1,
'type' => 'field',
'remote_name' => 'Title',
'my_name' => 'title',
'default_value' => 'http%3A%2F%2Ftest.com',
),
array(
'id' => 2,
'type' => 'field',
'remote_name' => 'BookType',
'my_name' => 'book-type',
'default_value' => '',
),
array(
'id' => 3,
'type' => 'value',
'remote_name' => 'dvd-disc',
'my_name' => 'dvd',
'default_value' => '',
),
);
$second = array(
'title' => 'Test',
'book-type' => 'dvd',
);
$map = array('fields' => array(), 'values' => array());
foreach ($first as $entry) {
switch ($entry['type']) {
case 'field':
$map['fields'][$entry['my_name']] = $entry['remote_name'];
break;
case 'value':
$map['values'][$entry['my_name']] = $entry['remote_name'];
break;
}
}
$new = array();
foreach ($second as $key => $val) {
$new[isset($map['fields'][$key]) ? $map['fields'][$key] : $key] = isset($map['values'][$val]) ? $map['values'][$val] : $val;
}
print_r($new);
Output:
Array
(
[Title] => Test
[BookType] => dvd-disc
)
Explanation:
The first loop collects the my_name/remote_name pairs for fields and values and makes them more accessible.
Like so:
Array
(
[fields] => Array
(
[title] => Title
[book-type] => BookType
)
[values] => Array
(
[dvd] => dvd-disc
)
)
The second loop will traverse $second and use the key/value pairs therein to populate $new. But while doing so will check for key/value duplicates in $map.
Keys or values not found in the map will be used as is.
foreach($arr1 as &$el) {
$el['remote_name'] = $arr2[$el['my_name']];
}
unset($el);
I am not aware of such a carrayzy function, but I know how you could do it:
//$array1 is first array, $array2 is second array
foreach($array1 as $key => $value){
if (isset($value['remote_name'], $value['my_name']) && $value['remote_name'] && $value['my_name']){
$my_name = $value['my_name'];
if (isset($array2[$my_name])) {
$remote_name = $value['remote_name'];
$array2[$remote_name] = $array2[$my_name];
//cleanup
unset($array2[$my_name]);
}
}
}

Categories