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;
}
Related
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);
}
}
I have array of object as
$a = [{"id":"20","invoice_id":"123"},{"id":"21","invoice_id":"123"},{"id":"22","invoice_id":"125"},{"id":"23","invoice_id":"125"},{"id":"24","invoice_id":"123"}];
here i want to create new array of abject in which duplicate object will not be there (invoice_id) as new array will be having first object of same invoice_id. i was doing like this.
foreach ($a as $key => $value) {
if(isset($new)) {
foreach ($new as $k => $val) {
if($val->id != $value->id) {
$new[] = $value;
}
}
}else{
$new[] = $value;
}
}
my new array will be like
$new = [{"id":"20","invoice_id":"123"},{"id":"22","invoice_id":"125"}]
but it is not giving desired output . What should be done ?
Since you tagged this as Laravel question use collections.
Less code (one line!) and performance hit is non-existent.
$a = json_decode('[{"id":"20","invoice_id":"123"},{"id":"21","invoice_id":"123"},{"id":"22","invoice_id":"125"},{"id":"23","invoice_id":"125"},{"id":"24","invoice_id":"123"}]');
$result = collect($a)->groupBy('invoice_id');
After OP edited question:
$result = collect($a)->unique('invoice_id')->values()->toArray();
results in:
=> [
{#826
+"id": "20",
+"invoice_id": "123",
},
{#824
+"id": "22",
+"invoice_id": "125",
},
]
or using ->toJson() instead of ->toArray()
"[{"id":"20","invoice_id":"123"},{"id":"22","invoice_id":"125"}]"
Please try the below code with simple logic,
$temp = $new = array();
$b = json_decode($a, true);
foreach ($b as $key => $val) {
if(!in_array($val['invoice_id'], $temp)) {
$temp[$val['id']] = $val['invoice_id'];
$new[] = array('id' => $val['id'], 'invoice_id' => $val['invoice_id']);
}
}
print_r($new);
I am just creating a temp array to store only the unique invoice_id to compare in a loop.
It gives the below result,
Array
(
[0] => Array
(
[id] => 20
[invoice_id] => 123
)
[1] => Array
(
[id] => 22
[invoice_id] => 125
)
)
$result = [];
foreach ($a as $data) {
$result[$data->id] = $data;
}
var_dump(array_values($results));
Try this
$a = json_decode($a);
$invoiceid = [];
$unique = [];
foreach ($a as $key => $value) {
if(!in_array($value->invoice_id,$invoiceid)) {
$invoiceid[] = $value->invoice_id;
$unique[] = $value;
}
}
echo $a = json_encode($unique);
I have a an array of products. Each product contains its category and subcategories listed in a hierarchical order:
Array
(
[product_id_1] => Array
(
[0] => Men
[1] => Sunglasses
[2] => Luxury
[3] => Ray-ban
)
[product_id_2] => Array
(
[0] => Women
[1] => Lenses
[2] => Casual
[3] => Gucci
)
[product_id_3] => Array
(
[0] => Men
[1] => Sunglasses
[2] => Casual
[3] => Prada
)
[...]
)
I want to create an unordered hierarchical HTML menu like so:
-Men
--Sunglasses
---Luxury
----Ray-ban
---Casual
----Prada
-Women
--Lenses
---Casual
----Gucci
The function should strip out repetitive categories and subcategories. This script returns the array of products that I've posted at the top:
<?php
function displayNestedMenu( $posts, $taxonomies ) {
foreach ( $posts as $post ) {
foreach ( $taxonomies as $key => $taxonomy ) {
$push = wp_get_object_terms( $post->ID, $taxonomy );
if ( !empty( $push ) ) {
$list[$post->ID][] = $push[0]->name;
}
}
}
return $list;
}
print_r( displayNestedMenu( $posts, $taxonomies ) );
?>
I imagine the solution should invoke the function inside the function but after trying a couple of methods I haven't succeeded yet. Any suggestions are appreciated!
Here is a simple idea :
$array = array(
'product_id_1' => array(
'Men',
'Sunglasses',
'Luxury',
'Ray-ban'
),
'product_id_2' => array(
'Women',
'Lenses',
'Casual',
'Gucci',
),
'product_id_3' => array(
'Men',
'Sunglasses',
'Casual',
'Prada'
)
);
The idea is to recreate the keys depending on the parent category, after that we sort them using ksort():
function tree($array){
$newArray = array();
foreach ($array as $arr) {
foreach ($arr as $key => $row) {
if ($key > 0) {
$index = array();
for ($i = 0; $i <= $key; $i++)
$index[] = $arr[$i];
$index = implode('_', $index);
} else
$index = $row;
$newArray[$index] = $row;
}
}
ksort($newArray);
return $newArray;
}
Then display the HTML :
$products = tree($array);
$i = 0;
echo '<ul style="list-style-type:none">';
foreach ($products as $key => $row) {
if(strcmp($row, $key) == 0 && $i != 0)
echo '</ul><br><ul style="list-style-type:none">';
++$i;
$level = count(explode('_', $key));
$padding = 15 * (--$level);
echo
'<li style="padding-left:' . $padding . 'px">
<span style="border-left:1px dashed black;border-bottom:1px dashed black;"> ' . $row . '</span>
</li>';
}
echo '</ul>';
PHP has powerful array features: string-indexed arrays can help provide solutions to problems like this one.
For the array conversion step:
$hrchy=array();
foreach($products AS $product){//$products is as per your first array, at start…
hrchy_ins($hrchy,$product);
}
function hrchy_ins(array &$hierarchy,array $product){//$hierarchy should be passed by reference…
if(\count($product)>0){//Condition necessary to implement base case, avoiding infinite recursion
if(!isset($hierarchy[$product[0]])){$hierarchy[$product[0]]=array();}//Conditional execution ignores duplicates…
if(\count($product)>1){hrchy_ins($hierarchy[$product[0]],\array_slice($product,1));}//Condition may not be strictly necessary (see condition above!)
} }
We might now use a recursive approach for a further HTML-writing step (the recursion secret sauce = a simple recursive function including a branch-on-condition for the base-case):
function prod_list(array $hierarchy){
if(\count($hierarchy)===0){
return '';
}else{
$list='';
$list.='<ul>';
foreach($hierarchy AS $cat => $children){
$list.='<li>'.$cat;
$list.=prod_list($children);//Recursive step…
$list.='</li>';
}
$list.='<ul>';
return $list;
}
}
Finally, after defining the function, we invoke it:
echo(prod_list($hrchy));
Disclaimer: I have not tested this code.
You could transform the array in a static way, as the structure you describe always has four parts;
$hierarchy = array();
foreach($products as $product_id => $product) {
list($gender, $category, $type, $brand) = $product;
$hierarchy[$gender][$category][$type][$brand][] = $product_id;
}
I am wondering if I could explain this.
I have a multidimensional array , I would like to get the count of particular value appearing in that array
Below I am showing the snippet of array . I am just checking with the profile_type .
So I am trying to display the count of profile_type in the array
EDIT
Sorry I've forgot mention something, not something its the main thing , I need the count of profile_type==p
Array
(
[0] => Array
(
[Driver] => Array
(
[id] => 4
[profile_type] => p
[birthyear] => 1978
[is_elite] => 0
)
)
[1] => Array
(
[Driver] => Array
(
[id] => 4
[profile_type] => d
[birthyear] => 1972
[is_elite] => 1
)
)
)
Easy solution with RecursiveArrayIterator, so you don't have to care about the dimensions:
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$counter = 0
foreach ($iterator as $key => $value) {
if ($key == 'profile_type' && $value == 'p') {
$counter++;
}
}
echo $counter;
Something like this might work...
$counts = array();
foreach ($array as $key=>$val) {
foreach ($innerArray as $driver=>$arr) {
$counts[] = $arr['profile_type'];
}
}
$solution = array_count_values($counts);
I'd do something like:
$profile = array();
foreach($array as $elem) {
if (isset($elem['Driver']['profile_type'])) {
$profile[$elem['Driver']['profile_type']]++;
} else {
$profile[$elem['Driver']['profile_type']] = 1;
}
}
print_r($profile);
You may also use array_walk($array,"test") and define a function "test" that checks each item of the array for 'type' and calls recursively array_walk($arrayElement,"test") for items of type 'array' , else checks for the condition. If condition satisfies, increment a count.
Hi You can get count of profuke_type==p from a multi dimensiona array
$arr = array();
$arr[0]['Driver']['id'] = 4;
$arr[0]['Driver']['profile_type'] = 'p';
$arr[0]['Driver']['birthyear'] = 1978;
$arr[0]['Driver']['is_elite'] = 0;
$arr[1]['Driver']['id'] = 4;
$arr[1]['Driver']['profile_type'] = 'd';
$arr[1]['Driver']['birthyear'] = 1972;
$arr[1]['Driver']['is_elite'] = 1;
$arr[2]['profile_type'] = 'p';
$result = 0;
get_count($arr, 'profile_type', 'd' , $result);
echo $result;
function get_count($array, $key, $value , &$result){
if(!is_array($array)){
return;
}
if($array[$key] == $value){
$result++;
}
foreach($array AS $arr){
get_count($arr, $key, $value , $result);
}
}
try this..
thanks
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.