Separating array rows into other arrays based on key name - php

I have an array like this
$rows = array(
array(
'fruit.name' => 'Apple',
'fruit.colour' => 'Red',
'fruit.weight' => '0.1',
'vegetable.name' => 'Carrot',
'vegetable.colour' => 'Orange',
'vegetable.weight' => '0.05'
),
array(
'fruit.name' => 'Banana',
'fruit.colour' => 'Yellow',
'fruit.weight' => '0.7',
'vegetable.name' => 'Potato',
'vegetable.colour' => 'Brown',
'vegetable.weight' => '0.6'
)
);
And i want to be able to sort the array into 2 other arrays called 'fruits' and 'vegetables' based on the first part of the key name so up to the decimal point. With this array I should have 2 rows in each of the fruits and vegetable arrays.
I have this code but it doesn't work and I can't see what I'm doing wrong.
$fruits = array();
$vegetables = array();
foreach($rows as $row)
{
foreach($row as $key => $value)
{
if('fruit' == substr($key, 0, strpos($key, '.')))
{
$fruits[$key] = $row;
}
else
{
$vegetables[$key] = $row;
}
}
}
echo "<pre>"; var_dump($fruits); echo "</pre>";
When i do a var_dump i get this
array(3) {
["fruit.name"]=>
array(6) {
["fruit.name"]=>
string(6) "Banana"
["fruit.colour"]=>
string(6) "Yellow"
["fruit.weight"]=>
string(3) "0.7"
["vegetable.name"]=>
string(6) "Potato"
["vegetable.colour"]=>
string(5) "Brown"
["vegetable.weight"]=>
string(3) "0.6"
}
["fruit.colour"]=>
array(6) {
["fruit.name"]=>
string(6) "Banana"
["fruit.colour"]=>
string(6) "Yellow"
["fruit.weight"]=>
string(3) "0.7"
["vegetable.name"]=>
string(6) "Potato"
["vegetable.colour"]=>
string(5) "Brown"
["vegetable.weight"]=>
string(3) "0.6"
}
["fruit.weight"]=>
array(6) {
["fruit.name"]=>
string(6) "Banana"
["fruit.colour"]=>
string(6) "Yellow"
["fruit.weight"]=>
string(3) "0.7"
["vegetable.name"]=>
string(6) "Potato"
["vegetable.colour"]=>
string(5) "Brown"
["vegetable.weight"]=>
string(3) "0.6"
}
}
Any help please getting this to separate the array into 2 arrays each containing either fruits or vegetables.

This seems to work:
$rows = array(
array(
'fruit.name' => 'Apple',
'fruit.colour' => 'Red',
'fruit.weight' => '0.1',
'vegetable.name' => 'Carrot',
'vegetable.colour' => 'Orange',
'vegetable.weight' => '0.05'
),
array(
'fruit.name' => 'Banana',
'fruit.colour' => 'Yellow',
'fruit.weight' => '0.7',
'vegetable.name' => 'Potato',
'vegetable.colour' => 'Brown',
'vegetable.weight' => '0.6'
)
);
$fruits = $vegs = array();
foreach ($rows as $arrays) {
$fruit = array();
$veg = array();
foreach ($arrays as $key => $val) {
$index = substr($key, strpos($key, ".") + 1);
if('fruit' == substr($key, 0, strpos($key, '.'))){
$fruit[$index] = $val;
} else {
$veg[$index] = $val;
}
}
$fruits[] = $fruit;
$vegs[] = $veg;
}
var_dump($fruits, $vegs);
(Please overlook the fact I've called one of the vars $vegs)
Hope this helps!

I didn't run the code, but it looks like you want:
$fruits[$key] = $value;
-AND-
$vegetables[$key] = $value;

Related

Multi-dimentional array how to get the nested value without foreach loop

I got output from one of the WordPress table cells. The following value is displayed.
$allcoinkey=get_option('_transient_mcw-custom-data');
var_dump($allcoinkey);
and the output:
[0]=>
array(2) {
["slug"]=>
string(7) "bitcoin"
["keywords"]=>
string(30) "بیتکوین,بیت کوین"
}
[1]=>
array(2) {
["slug"]=>
string(8) "ethereum"
["keywords"]=>
string(27) "اتریوم,اتاریوم"
}
}
How do I access keyword values where slug=bitcoin without foreach?
i use this sample code:
<?php
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
$key = array_search('red', $array); // $key = 1;
?>
You can do it like this:
<?php
$allcoinkey = [
[
'slug' => 'bitcoin',
'keywords' => 'بیتکوین,بیت کوین',
],
[
'slug' => 'ethereum',
'keywords' => 'اتریوم,اتاریوم',
],
];
$bitcoinKeywords = current(array_filter($allcoinkey, static function (array $cryptoCurrency) {
return $cryptoCurrency['slug'] === 'bitcoin';
}))['keywords'];
echo $bitcoinKeywords;

array_combine results only one result [duplicate]

This question already has answers here:
array_combine is return only last value
(2 answers)
Closed 3 years ago.
I am using the following code to get two arrays into one json result. But getting only the first index as result. Is there any error in the code or anybody can suggest an alternate method to get the same result.
$array1 = $_POST['array1'];
$array2 = $_POST['array2'];
$jsonArray = array();
foreach (array_combine( $array1, $array2 ) as $name => $value) {
$jsonArray[] = array('name' => $name, 'value' => $value);
}
echo $json = json_encode($jsonArray);
$_POST['array1'] = array(4) {
[0]=>
string(3) "day1"
[1]=>
string(3) "day2"
[2]=>
string(3) "day3"
[3]=>
string(3) "day4"
}
$_POST['array2'] = array(4) {
[0]=>
string(3) "item1"
[1]=>
string(3) "item2"
[2]=>
string(3) "item3"
[3]=>
string(3) "item4"
}
Expected result should be like
[{"name":"day1","value":"item1"},{"name":"day2","value":"item2"},{"name":"day3","value":"item3"}]
Try this,
$arr1 = array('0' => 'day1', '1' => 'day2', '2' => 'day3', '3' => 'day4');
echo'<pre>';print_r($arr1);
$arr2 = array('0' => 'item1','1' => 'item2','2' => 'item3','3' => 'item4');
echo'<pre>';print_r($arr2);
echo'<pre>';print_r(array_combine($arr1, $arr2));
$newArray = array();
foreach(array_combine($arr1, $arr2) as $key => $value){
array_push($newArray, array('name'=> $key,'value'=>$value));
}
echo'<pre>';print_r($newArray);
echo json_encode($newArray);die;

Recursion with multidimensional array

I have been working on this for long and I got it working as I want but I think there is simpler solution.
So far I got this:
$menu = array(
0 => (object) array(
'cat_id' => 1,
'cat_parent' => 0,
'cat_name' => 'domov',
'cat_href' => 'domov',
'cat_subcategories' => array()
),
1 => (object) array(
'cat_id' => 2,
'cat_parent' => 0,
'cat_name' => 'clanky',
'cat_href' => 'clanky',
'cat_subcategories' => array(
0 => (object) array(
'cat_id' => 9,
'cat_parent' => 2,
'cat_name' => 'apple clanky',
'cat_href' => 'apple',
'cat_subcategories' => array(
0 => (object) array(
'cat_id' => 11,
'cat_parent' => 9,
'cat_name' => 'iphone clanky',
'cat_href' => 'iphone',
'cat_subcategories' => array()
),
1 => (object) array(
'cat_id' => 12,
'cat_parent' => 9,
'cat_name' => 'macbook clanky',
'cat_href' => 'macbook',
'cat_subcategories' => array()
)
)
),
1 => (object) array(
'cat_id' => 10,
'cat_parent' => 2,
'cat_name' => 'microsoft clanky',
'cat_href' => 'microsoft',
'cat_subcategories' => array()
),
)
),
2 => (object) array(
'cat_id' => 3,
'cat_parent' => 0,
'cat_name' => 'produkty',
'cat_href' => 'produkty',
'cat_subcategories' => array()
),
3 => (object) array(
'cat_id' => 4,
'cat_parent' => 0,
'cat_name' => 'vyrobcovia',
'cat_href' => 'vyrobcovia',
'cat_subcategories' =>
array(
0 => (object) array(
'cat_id' => 5,
'cat_parent' => 4,
'cat_name' => 'apple',
'cat_href' => 'apple',
'cat_subcategories' => array(
0 => (object) array(
'cat_id' => 7,
'cat_parent' => 5,
'cat_name' => 'iphone',
'cat_href' => 'iphone',
'cat_subcategories' => array()
),
1 => (object) array(
'cat_id' => 8,
'cat_parent' => 5,
'cat_name' => 'macbook',
'cat_href' => 'macbook',
'cat_subcategories' => array()
)
)
),
1 => (object) array(
'cat_id' => 6,
'cat_parent' => 4,
'cat_name' => 'microsoft',
'cat_href' => 'microsoft',
'cat_subcategories' => array()
),
)
),
);
function generate_menu($menu, $level = 1, $tmp_array = array())
{
foreach($menu as $key => $c)
{
$menu_item = get_menu_elements($c, $level);
$tmp_array = array_replace_recursive($tmp_array, $menu_item);
foreach($c->cat_subcategories as $_key => $_c)
{
$menu_item = get_menu_elements($_c, $level+1);
$tmp_array = array_replace_recursive($tmp_array, $menu_item);
foreach($_c->cat_subcategories as $__key => $__c)
{
$menu_item = get_menu_elements($__c, $level+2);
$tmp_array = array_replace_recursive($tmp_array, $menu_item);
}
}
}
return $tmp_array;
}
function get_menu_elements($c, $level = 1)
{
$level_var = "level_".($level);
$output = array(
$level_var => array()
);
$output[$level_var][$c->cat_id] = array(
'parent' => $c->cat_parent,
'html' => $c->cat_name
);
return $output;
}
In the end I should have multidimensional array with:
array(3) {
["level_1"]=>
array(4) {
[1]=>
array(2) {
["parent"]=>
int(0)
["html"]=>
string(5) "domov"
}
[2]=>
array(2) {
["parent"]=>
int(0)
["html"]=>
string(6) "clanky"
}
[3]=>
array(2) {
["parent"]=>
int(0)
["html"]=>
string(8) "produkty"
}
[4]=>
array(2) {
["parent"]=>
int(0)
["html"]=>
string(10) "vyrobcovia"
}
}
["level_2"]=>
array(4) {
[9]=>
array(2) {
["parent"]=>
int(2)
["html"]=>
string(12) "apple clanky"
}
[10]=>
array(2) {
["parent"]=>
int(2)
["html"]=>
string(16) "microsoft clanky"
}
[5]=>
array(2) {
["parent"]=>
int(4)
["html"]=>
string(5) "apple"
}
[6]=>
array(2) {
["parent"]=>
int(4)
["html"]=>
string(9) "microsoft"
}
}
["level_3"]=>
array(4) {
[11]=>
array(2) {
["parent"]=>
int(9)
["html"]=>
string(13) "iphone clanky"
}
[12]=>
array(2) {
["parent"]=>
int(9)
["html"]=>
string(14) "macbook clanky"
}
[7]=>
array(2) {
["parent"]=>
int(5)
["html"]=>
string(6) "iphone"
}
[8]=>
array(2) {
["parent"]=>
int(5)
["html"]=>
string(7) "macbook"
}
}
}
I want to print multi-level menu recursion. I got it working with this code but in function generate_menu I had to use 3 foreach loops for cat_subcategories. When I used recursion like this:
function generate_menu($menu, $level = 1, $tmp_array = array())
{
foreach($menu as $key => $c)
{
$menu_item = get_menu_elements($c, $level);
$tmp_array = array_replace_recursive($tmp_array, $menu_item);
if (!empty($c->cat_subcategories)) generate_menu($c->cat_subcategories, $level + 1, $tmp_array);
}
return $tmp_array;
}
i got only 'level_1' in output
The output which I am getting now is the same I want I just want to simplify the multiple foreach()
etc. Basicaly
level_1 - first loop of $menu
level_2 - loop of cat_subcategories
level_3 - loop of cat_subcategories for cat_subcategories item
You essentially need to perform a breadth-first traversal in your menu tree. For that I would suggest an iterative function instead of a recursive function, as the latter is more suitable for a depth-first traversal.
Here is the function:
function generate_menu($menu) {
$result = [];
$level = 1;
while (count($menu)) {
$queue = [];
$items = [];
foreach($menu as $cat) {
$items[$cat->cat_id] = [
"parent" => $cat->cat_parent,
"html" => $cat->cat_name
];
$queue = array_merge($queue, $cat->cat_subcategories);
}
$result["level_$level"] = $items;
$level++;
$menu = $queue;
}
return $result;
}
See it run on eval.in.
As this function traverses the top level of the tree, it collects all the children into $queue. Once the top level has been translated into the output (in the level_1 key), that queue will have all second level entries. This then is moved to $menu, and the process is repeated, but now with level_2. This continues until a level is reached where no more entries are found.
I've made some time ago this function. It could help you.
I've got an array where $arr[actual item][parental id]
function getChild($id, $result, $count) {
for( $i = 0; $i < sizeof($result); $i ++) {
if( $result[$i][2] == $id) {
getChild($result[$i][0], $result, $count + 1);
}
}
}
EDIT
In my case, where all the items in the one-dimensional array, but with the hierarchy of n-dimensional array depended on the parental id.
CODE TO PRINT MENU
This code will work for N-number of hierarchy
static function printAllCategoriesAsCheckbox($arr, $d=0){
$htmlString = "";
if (is_array($arr)){
foreach($arr as $category){
$htmlString = $htmlString . '<div><input style="margin-left: ' . 30*$d . 'px;" value="'.$category->id.'" class="category-input" type="checkbox" name="category_id[]">';
$htmlString = $htmlString . ' <label for="category_'.$category->id.'">' . $category->name . '</label></div>';
if (is_array($category['childs'])){
$htmlString = $htmlString . ItemCategory::printAllCategoriesAsCheckbox($category['childs'], $d+1);
}
}
}
return $htmlString;
}

Execute function on every value of a key

I have an array with the following structure :
$array = array(
array("animal" => "dog","color" => "black"),
array("animal" => "cat","color" => "white"),
array("animal" => "mouse","color" => "grey")
);
Now I need to execute a function on every value of animal, say make the values uppercase. This is the expected output :
array(3) {
[0]=>
array(2) {
["animal"]=>
string(3) "DOG"
["color"]=>
string(5) "black"
}
[1]=>
array(2) {
["animal"]=>
string(3) "CAT"
["color"]=>
string(5) "white"
}
[2]=>
array(2) {
["animal"]=>
string(5) "MOUSE"
["color"]=>
string(4) "grey"
}
}
When I do
for (int i=0; i<=$array.size(); i++) {
$array["animal"] = array_map('strtoupper', $array["animal"]);
}
I get this error:
<b>Parse error</b>: syntax error, unexpected 'i' (T_STRING), expecting ';' in <b>[...][...]</b> on line <b>15</b><br />
You can achieve this using following ways:
<?php
$array = array(
array("animal"=>"dog","color"=>"black"),
array("animal"=>"cat","color"=>"white"),
array("animal"=>"mouse","color"=>"grey")
);
foreach ($array as $key => $value) {
foreach ($value as $key1 => $value1) {
if($key1 == 'animal'){
$keys = ucfirst($value1);
$array[$key][$key1]=$keys;
}
}
}
echo "<pre>";print_r($array);
?>
You can also use array_walk Function of PHP
array_walk
$array = array(
array("animal"=>"dog","color"=>"black"),
array("animal"=>"cat","color"=>"white"),
array("animal"=>"mouse","color"=>"grey")
);
$array_map = array_walk($array, 'walk_array');
function walk_array(&$item, $key){
$item['animal'] = strtoupper($item['animal']);
}
echo '<pre>';
print_r($array);
Solution
You could use a for() loop to iterate through you animals. You'll have to count the number of animals you got first with the count() function cast to a variable. Then, you'll be able to make uppercase on your animal index with the strtoupper() function. Also note that you can use the new PHP syntax for arrays like so [] which is a quicker way to do it.
Source-code
<?php
$animals = [
[
'animal' => 'dog',
'color' => 'black'
],
[
'animal' => 'cat',
'color' => 'white'
],
[
'animal' => 'mouse',
'color' => 'grey'
]
];
for ($i = 0; $i < count($animals); $i++)
{
$animals[$i]['animal'] = strtoupper($animals[$i]['animal']);
}
echo '<pre>';
print_r($animals);
echo '</pre>';
Result
Array
(
[0] => Array
(
[animal] => DOG
[color] => black
)
[1] => Array
(
[animal] => CAT
[color] => white
)
[2] => Array
(
[animal] => MOUSE
[color] => grey
)
)
Demo.
PHP : for loop.
PHP : count().
PHP : strtoupper().
PHP : arrays.

PHP $_POST data into Variable

I have following $_POST data from the form fieldset
array(2) {
["item-1"] =>
array(2) {
["name"]=> string(5) "apple"
["price"]=> string(1) "5"
}
["item-2"] =>
array(2) {
["name"]=> string(6) "orange"
["price"]=> string(1) "2"
}
}
I want to store this post data into variables using foreach such as $name_1 $price_1 & $name_2 $price_2
How can I parse this form-data ?
Altough I think it's completely unlogical to use variables this way, this can help you out.
It created the variables automatically using the given information..
//array with values
$source = [
'item-1' => [
'name' => 'apple',
'price' => '5',
],
'item-2' => [
'name' => 'orange',
'price' => '2'
]
];
foreach($source as $k=>$array) {
//get all integer values from the key
$int = preg_replace('/[^0-9]/', '', $k);
//foreach property in $array, create the variable name + the integer number
//as a variable and set the value belonging to the key
foreach($array as $name=>$value) {
${$name . '_' . $int} = $value;
}
}
$i = 1;
foreach($_POST as $data) {
${'name_' . $i} = $data["name"];
${'price_' . $i} = $data["price"];
$i++;
}
foreach ($_POST as $k => $v) {
$i = +preg_replace('/item-(\d+)/', '$1', $k);
foreach(array('name', 'price') as $name) {
$key = "$name_$i";
$$key = $v[$name];
}
Hope it helps.
Try this..
<?php
$response =
array(
'item-1' => array(
2 => array(
'name' => 'apple',
'price' => 5
),
),
'item-2' => array(
2 => array(
'name' => 'orange',
'price' => 2
),
),
);
foreach($response as $key =>$value)
{
$k=explode("-",$key);
$keyvalue=end($k);
foreach($value as $result)
{
echo ${'name_' . $keyvalue}=$result['name'];
echo "</br>";
echo ${'price_' . $keyvalue}=$result['price'];
echo "</br>";
}
}
?>

Categories