PHP Array Iteration to Flatten All Possible Results - php

I don't know the term of what I am trying to do, so I can't seem to find a similar answer.
I'm trying to make an array that looks like the following:
array (
'birds' => array(
'parakeet',
'conure',
'woodpecker'),
'color' => array(
'red',
'blue',
'green'
),
'size' => array(
'large',
'medium',
'small'
));
to iterate through all possible permutations to look like the following
array(
array('parakeet','red','large'),
array('parakeet','red','medium'),
array('parakeet','red','small'),
array('parakeet','blue','large'),
array('parakeet','blue','medium'),
array('parakeet','blue','small'),
array('parakeet','green','large'),
array('parakeet','green','medium'),
array('parakeet','green','small'),
array('conure','red','large'),
..... etc
);
Any help would be very much appreciated! Thank you in advance!

Just create a step down loop on each level for bird, color and size. Then create a temporary container and continually merge it:
$data = [[]]; // initialize empty container
foreach ($arr as $key => $values) {
$tmp = []; // store it in here
foreach ($data as $d) {
foreach ($values as $value) {
$tmp[] = array_merge($d, [$value]); // then continually merge
}
}
$data = $tmp;
}

Just loop through what you need to, and build a new array as you go:
$newarray = $temparray = array();
foreach ( $oldarray['birds'] as $bird )
{
$temparray[] = $bird;
foreach ( $oldarray['color'] as $color )
{
$temparray[] = $color;
foreach ( $oldarray['size'] as $size )
{
$temparray[] = $size;
}
$newarray[] = $temparray;
unset ($temparray);
}
}

Related

php array returning same values in loop

I am trying to loop through each key but i am facing a problem of same value repeating inside for each loop
Here is example of my current code and result (click here)
here is my code so far
<?php
$data2 = array(
'category_name' => '33287*100*prescription*1,32457*1250*lab*1'
);
$result = array('0' => (object)$data2);
foreach ($result as $key => $category) {
$category_name = explode(',', $category->category_name);
}
$newresults=[];
foreach ($category_name as $key) {
$category->category_name = $key;
$newresults[]=$category;
}
$result=$newresults;
$newresults=[];
$category->items_count = 0;
foreach ($result as $key => $value) {
list($sale_key, $sale_value) = explode('*', $value->category_name);
// $category->items_count += count($sale_value);
$newresults[]=$category;
}
$result=$newresults;
i am expect the result should be
Array
(
[0] => stdClass Object
(
[category_name] => 33287*100*prescription*1
[items_count] => 0
)
[1] => stdClass Object
(
[category_name] => 32457*1250*lab*1
[items_count] => 0
)
)
The bug is that you're relying only on the last version of $category after you've finished looping it earlier - you'd have to be using it within the loop where it's assigned, in order to get each value in turn, or you could use $value from your last foreach loop.
But as a general observation, this code has way too many loops etc. just for processing one array in the way you've requested. Here's a much simpler version:
$category_name = '33287*100*prescription*1,32457*1250*lab*1';
$category_name_arr = explode(',', $category_name);
print_r($category_name_arr);
$newresults=[];
foreach ($category_name_arr as $cat) {
$newresults[] = (object) array("category_name" => $cat, "items_count" => 0);
}
print_r($newresults);
Demo: http://sandbox.onlinephpfunctions.com/code/065a32b40f67e00aa85f0f5b58ecacd510f2f38a
If you still need to be able to support multiple lines of input, you can do it like this, by just merging the exploded arrays before you process them:
$data = array(
'33287*100*prescription*1,32457*1250*lab*1',
'33222*900*prescription*3,22233*1200*lab*2',
);
$category_name_arr = [];
foreach ($data as $category_name)
{
$category_name_arr = array_merge($category_name_arr, explode(',', $category_name));
}
print_r($category_name_arr);
$newresults=[];
foreach ($category_name_arr as $cat) {
$newresults[] = (object) array("category_name" => $cat, "items_count" => 0);
}
print_r($newresults);
adding $category = new stdClass();
foreach ($category_name as $key) {
$category = new stdClass();
$category->category_name = $key;
$newresults[]=$category;
}

PHP- how to sum array elements with duplicate element value [duplicate]

This question already has answers here:
Group 2d array rows by one column and sum another column [duplicate]
(3 answers)
Closed 4 months ago.
I have a multi array that has some duplicated values that are same by name ( name is an element )
i want to sum quantity of each array that has same name , and then unset the second array
Example :
<?php
$Array=array(
0=>array("name"=>"X","QTY"=>500),
1=>array("name"=>"y","QTY"=>250),
2=>array("name"=>"X","QTY"=>250)
);
?>
Now i want to sum duplicated values as below.
Result :
<?php
$Array=array(
0=>array("name"=>"X","QTY"=>750),
1=>array("name"=>"y","QTY"=>250)
);
?>
UPDATED
i found this function to search in array , foreach and another loops does not works too
<?php
function search($array, $key, $value)
{
$results = array();
if (is_array($array)) {
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
$results = array_merge($results, search($subarray, $key, $value));
}
}
return $results;
}
?>
<?php
$Array=array(
0=>array("name"=>"X","QTY"=>500),
1=>array("name"=>"y","QTY"=>250),
2=>array("name"=>"X","QTY"=>250)
);
$result = array();
$names = array_column($Array, 'name');
$QTYs = array_column($Array, 'QTY');
$unique_names = array_unique($names);
foreach ($unique_names as $name){
$this_keys = array_keys($names, $name);
$qty = array_sum(array_intersect_key($QTYs, array_combine($this_keys, $this_keys)));
$result[] = array("name"=>$name,"QTY"=>$qty);
}
var_export($result); :
array (
0 =>
array (
'name' => 'X',
'QTY' => 750,
),
1 =>
array (
'name' => 'y',
'QTY' => 250,
),
)
Try this simplest one, Hope this will be helpful.
Try this code snippet here
$result=array();
foreach ($Array as $value)
{
if(isset($result[$value["name"]]))
{
$result[$value["name"]]["QTY"]+=$value["QTY"];
}
else
{
$result[$value["name"]]=$value;
}
}
print_r(array_values($result));
Try this, check the live demo.
<?php
$Array=array(
0=>array("name"=>"X","QTY"=>500),
1=>array("name"=>"y","QTY"=>250),
2=>array("name"=>"X","QTY"=>250)
);
$keys = array_column($Array, 'name');
$QTYs = array_column($Array, 'QTY');
$result = [];
foreach($keys as $k => $v)
{
$result[$v] += $QTYs[$k];
}
print_r($result);
You can achieve this by creating an array with name as key and then iterating over all values and add them together, resulting in this
function sum_same($array) {
$keyArray = [];
foreach ($array as $entry) {
$name = $entry["name"];
if(isset($keyArray[$name])) {
$keyArray[$name] += $entry["QTY"];
} else {
$keyArray[$name] = $entry["QTY"];
}
}
// Convert the keyArray to the old format.
$resultArray = [];
foreach ($keyArray as $key => $value) {
$resultArray[] = ["name" => $key, "QTY" => $value];
}
return $resultArray;
}
Try the code here
If you want to alter the old array use the function like this:
$myArray = sum_same($myArray);
The old array will be overwritten by the new one.
This problem is a classic example of usage for array_reduce():
$Array = array(
0 => array('name' => 'X', 'QTY' => 500),
1 => array('name' => 'y', 'QTY' => 250),
2 => array('name' => 'X', 'QTY' => 250),
);
// array_values() gets rid of the keys of the array produced by array_reduce()
// they were needed by the callback to easily identify the items in the array during processing
$Array = array_values(array_reduce(
$Array,
function (array $a, array $v) {
$k = $v['name'];
// Check if another entry having the same name was already processed
// Keep them in the accumulator indexed by name
if (! array_key_exists($k, $a)) {
$a[$k] = $v; // This is the first entry with this name
} else {
// Not the first one; update the quantity
$a[$k]['QTY'] += $v['QTY'];
}
return $a; // return the partial accumulator
},
array() // start with an empty array as accumulator
));

Restructure an array

I have this array in PHP
$fields = array(
0 => array(
'field1' => 'something1',
'field2' => 'something2'
)
)
And I need it to look like this
$fields = array(
'fields1' => 'something1',
'fields2' => 'something2'
)
What function code can I use to get rid of the 0 index in the example?
You can loop through like this...
Create new array
$newArray = [];
Then loop through
foreach($fields as $field){
if(is_array($field)){
foreach($field as $key => $value){
$newArray[$key] = $value;
}
}
}
just take the '0' element from fields:
$fields=$fields[0];
Simple
$fields = reset($fields);
Or
$fields = array_shift($fields);
Create an array, loop through $fields, and merge whatever items are there with the created array.
$final_array = array();
foreach ($fields as $field)
{
$final_array = array_merge($final_array, $field);
}
$fields = $final_array;
This will be able to handle any number of items in either level of the array and compact them into a one-level array.
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($data)); $list = iterator_to_array($it,false);
Use this to get ride of any extra levels.
Will gives you what you want

Loop through a multi dimensional array checking a specific key for repeat values in PHP

I have a multi dimensional array that I have got from a database and I want to check this array for duplicate data and store it in another array of duplicates. my code is as follows
//create temp array
$tmp = array();
foreach ($matchingarray as $nameKey => $match) {
// loop through and stoe the contents of that array to another so i can compare
$tmp[] = $match;
}
// create an array to store duplicates
$duplicatesArray = array();
// if the temp array is not empty then loop through both arrays
if (! empty($tmp)) {
foreach ($tmp as $key => $tmpvalue) {
foreach ($matchingarray as $key => $match) {
// if a key name is the same in both arrays then add it tothe duplicates array
if ($tmpvalue['name'] == $match['name']) {
$duplicatesArray = $match;
}
}
}
}
//count how many are duplicates
$dups = count($duplicatesArray);
What I would like to know is this the right logic?
I will take where Igoel left off
there is 1 error and also 1 suggest that i will make.
Error:
you cannot reuse $key twice in the foreach because they will override.
Suggestion as what Igoel stated: your best bet for duplicate effectively is to use sql. SQL is faster at processing than looping through arrays. Don't forget you need to load the data into memory and thats costly.
Try this way
<?php
static $cnt = array();
$min = 1;
$coll = array(
'dep1' => array(
'fy' => array('john', 'johnny', 'victor'),
'sy' => array('david', 'arthur'),
'ty' => array('sam', 'joe', 'victor')
),
'dep2' => array(
'fy' => array('natalie', 'linda', 'molly'),
'sy' => array('katie', 'helen', 'sam', 'ravi', 'vipul'),
'ty' => array('sharon', 'julia', 'maddy')
)
);
function recursive_search(&$v, $k){
global $cnt;
$cnt[] = $v;
}
array_walk_recursive($coll, 'recursive_search');
$newNumbers = array_filter(
array_count_values($cnt),
function ($value) use($min) {
return ($value > $min);
}
);
echo "Values > 1 are repeated \n";
print_r(array_count_values($cnt));
echo "Values repeted\n";
print_r($newNumbers);
DEMO

PHP rename array keys in multidimensional array

In an array such as the one below, how could I rename "fee_id" to "id"?
Array
(
[0] => Array
(
[fee_id] => 15
[fee_amount] => 308.5
[year] => 2009
)
[1] => Array
(
[fee_id] => 14
[fee_amount] => 308.5
[year] => 2009
)
)
foreach ( $array as $k=>$v )
{
$array[$k] ['id'] = $array[$k] ['fee_id'];
unset($array[$k]['fee_id']);
}
This should work
You could use array_map() to do it.
$myarray = array_map(function($tag) {
return array(
'id' => $tag['fee_id'],
'fee_amount' => $tag['fee_amount'],
'year' => $tag['year']
); }, $myarray);
$arrayNum = count($theArray);
for( $i = 0 ; $i < $arrayNum ; $i++ )
{
$fee_id_value = $theArray[$i]['fee_id'];
unset($theArray[$i]['fee_id']);
$theArray[$i]['id'] = $fee_id_value;
}
This should work.
Copy the current 'fee_id' value to a new key named 'id' and unset the previous key?
foreach ($array as $arr)
{
$arr['id'] = $arr['fee_id'];
unset($arr['fee_id']);
}
There is no function builtin doing such thin afaik.
This is the working solution, i tested it.
foreach ($myArray as &$arr) {
$arr['id'] = $arr['fee_id'];
unset($arr['fee_id']);
}
The snippet below will rename an associative array key while preserving order (sometimes... we must). You can substitute the new key's $value if you need to wholly replace an item.
$old_key = "key_to_replace";
$new_key = "my_new_key";
$intermediate_array = array();
while (list($key, $value) = each($original_array)) {
if ($key == $old_key) {
$intermediate_array[$new_key] = $value;
}
else {
$intermediate_array[$key] = $value;
}
}
$original_array = $intermediate_array;
Converted 0->feild0, 1->field1,2->field2....
This is just one example in which i get comma separated value in string and convert it into multidimensional array and then using foreach loop i changed key value of array
<?php
$str = "abc,def,ghi,jkl,mno,pqr,stu
abc,def,ghi,jkl,mno,pqr,stu
abc,def,ghi,jkl,mno,pqr,stu
abc,def,ghi,jkl,mno,pqr,stu;
echo '<pre>';
$arr1 = explode("\n", $str); // this will create multidimensional array from upper string
//print_r($arr1);
foreach ($arr1 as $key => $value) {
$arr2[] = explode(",", $value);
foreach ($arr2 as $key1 => $value1) {
$i =0;
foreach ($value1 as $key2 => $value2) {
$key3 = 'field'.$i;
$i++;
$value1[$key3] = $value2;
unset($value1[$key2]);
}
}
$arr3[] = $value1;
}
print_r($arr3);
?>
I wrote a function to do it using objects or arrays (single or multidimensional) see at https://github.com/joaorito/php_RenameKeys.
Bellow is a simple example, you can use a json feature combine with replace to do it.
// Your original array (single or multi)
$original = array(
'DataHora' => date('YmdHis'),
'Produto' => 'Produto 1',
'Preco' => 10.00,
'Quant' => 2);
// Your map of key to change
$map = array(
'DataHora' => 'Date',
'Produto' => 'Product',
'Preco' => 'Price',
'Quant' => 'Amount');
$temp_array = json_encode($original);
foreach ($map AS $k=>$v) {
$temp_array = str_ireplace('"'.$k.'":','"'.$v.'":', $temp);
}
$new_array = json_decode($temp, $array);
Multidimentional array key can be changed dynamically by following function:
function change_key(array $arr, $keySetOrCallBack = [])
{
$newArr = [];
foreach ($arr as $k => $v) {
if (is_callable($keySetOrCallBack)) {
$key = call_user_func_array($keySetOrCallBack, [$k, $v]);
} else {
$key = $keySetOrCallBack[$k] ?? $k;
}
$newArr[$key] = is_array($v) ? array_change_key($v, $keySetOrCallBack) : $v;
}
return $newArr;
}
Sample Example:
$sampleArray = [
'hello' => 'world',
'nested' => ['hello' => 'John']
];
//Change by difined key set
$outputArray = change_key($sampleArray, ['hello' => 'hi']);
//Output Array: ['hi' => 'world', 'nested' => ['hi' => 'John']];
//Change by callback
$outputArray = change_key($sampleArray, function($key, $value) {
return ucwords(key);
});
//Output Array: ['Hello' => 'world', 'Nested' => ['Hello' => 'John']];
I have been trying to solve this issue for a couple hours using recursive functions, but finally I realized that we don't need recursion at all. Below is my approach.
$search = array('key1','key2','key3');
$replace = array('newkey1','newkey2','newkey3');
$resArray = str_replace($search,$replace,json_encode($array));
$res = json_decode($resArray);
On this way we can avoid loop and recursion.
Hope It helps.

Categories