I got array like this
$specials = array( 1 => array('word' => array('first', 'two', 'three'), 'digit' => array(1,2,3)),
2 => array('word' => array('four','five', 'six'), 'digit' => array(4,5,6)),
3 => array('word' => array('seven', 'eight', 'nine'), 'digit' => array(7,8,9)),
4 => array('word' => array('ten','eleven', 'twelve'), 'digit' => array(10,11,12))
);
and why i got to foreach 3 times like this
foreach($specials as $val) {
foreach($val as $valData) {
foreach($valData as $value) {
echo $value.'<br/>';
}
}
}
But how to loop or foreach correctly and with their index name like this ?
echo $value['word'];
echo $value['digit'];
i got error warning if echo $value['digit']
Warning: Illegal string offset 'digit' in ~/public_html/test/array.php on line 58
i need those output for different HTML and CSS each Value
<div class="digit"><?=$value['digit']?></div>
<div class="word"><?=$value['word']?></div>
foreach($specials as $val) {
foreach($val as $key => $valData) {
// $key is now either 'word' or 'digit'
foreach($valData as $value) {
echo "<div class='$key'>$value</div>";
}
}
}
Related
We are running a PHP code on a huge list (array with 5 millions elements).
The list format is as follows below (it looks "weird" at first look but this is the best format so far we came out in order to optimize the speed of the code down below)
$array = array(
array(1 => true,3 => true),
array(2 => true,4 => true,6 => true),
array(3 => true,5 => true),
array(5 => true),
array(4 => true,8 => true,10 => true),
array(200 => true,300 => true)
);
We want to combine similar elements from the array above and get to this result:
$final_array = array(
array(1,3,5),
array(2,4,6,8,10),
array(200,300)
);
Instead of using array(1,3) we decided to use array(1 => true,3 => true) because using keys instead of values (to store information) makes the code below runs faster and it outputs $final_array as above.
foreach ($array as $key1 => $value1) {
foreach ($array as $key2 => $value2) {
if ($key1 != $key2) {
foreach ($array[$key1] as $key3 => $value3) {
if (isset($array[$key2][$key3])) {
$array[$key2] = $array[$key2] + $array[$key1];
unset($array[$key1]);
break 2;
}
}
}
}
}
However this code above is still very slow. Could you find a better way to aggregate similar elements to each other on a faster code?
How about using array_intersect_key instead of third loop?
$array = array(
array(1 => true,3 => true),
array(2 => true,4 => true,6 => true),
array(3 => true,5 => true),
array(5 => true),
array(4 => true,8 => true,10 => true),
array(200 => true,300 => true)
);
foreach ($array as $key => $value) {
foreach ($array as $key2 => $value2) {
if ($key !== $key2 && !empty(array_intersect_key($value, $value2))) {
$array[$key] = $value2 + $value;
unset($array[$key2]);
}
}
}
print_r($array);
Working example
Edit #1:
For better performance try this variant:
$array = array(
array(1 => true,3 => true),
array(2 => true,4 => true,6 => true),
array(3 => true,5 => true),
array(5 => true),
array(4 => true,8 => true,10 => true),
array(200 => true,300 => true)
);
$count = count($array);
for ($i = 0; $i < $count - 1; ++$i) {
for ($j = $i + 1; $j < $count; ++$j) {
if (!empty(array_intersect_key($array[$i], $array[$j]))) {
$array[$j] = $array[$i] + $array[$j];
unset($array[$i]);
continue 2;
}
}
}
Working example #2
$arr = array('Hello','World!','Beautiful','Day!');
echo join(" ",$arr);
See Details
I have a very simple multidimensional array and some PHP code. The code should print the p_id values, but it does not do it. Do I really have to add one foreach more or is there other ways?
And here is the array:
Array (
[2764] => Array (
[status] => 0
[0] => Array (
[p_id] => 2895
)
[1] => Array (
[p_id] => 1468
)
)
[5974] => Array (
[status] => 0
[0] => Array (
[p_id] => 145
)
[1] => Array (
[p_id] => 756
)
)
)
Here is my PHP code:
foreach($arr as $innerArray)
foreach($innerArray as $key => $value)
echo $key . "=>" . $value . "<br>";
It prints:
status=>0
0=>Array
1=>Array
status=>0
0=>Array
1=>Array
foreach($arr as $a => $a_value)
{
echo $a . '<br>';
foreach($a_value as $av_arr => $av)
{
if(!is_array($av))
{
echo $av_arr . '=>' . $av . '<br>';
}
else
{
foreach($av as $inner_av => $inner_av_val)
{
echo $inner_av . '=>' . $inner_av_val . '<br>';
}
}
}
}
This simple call to array_walk_recursive() produces the output requested in the question:
array_walk_recursive(
$arr,
function ($value, $key) {
echo $key . "=>" . $value . "<br>";
}
);
But it doesn't make much sense as the output mixes the values of status with the values of p_id.
I would go for a more structured display using the original code with a little more meaning for the names of the variables:
foreach ($arr as $catId => $catInfo) {
// Category ID and details; use other names if I'm wrong
printf("Category: %d (status: %s)\n", $catId, $catInfo['status'] ? 'active' : 'inactive');
foreach ($catInfo as $key => $value) {
if ($key == 'status') {
// Ignore the status; it was already displayed
continue;
}
foreach ($value as $prodInfo) {
printf(" Product ID: %d\n", $prodInfo['p_id']);
}
}
}
The structure of the input array tells me you should first fix the code that generates it. It should group all the products (the values that are now indexed by numeric keys) into a single array. It should look like this:
$input = array(
'2764' => array(
'status' => 0,
'products' => array(
2895 => array(
'p_id' => 2895,
'name' => 'product #1',
// more product details here, if needd
),
1468 => array(
'p_id' => 1468,
'name' => 'product #2',
),
// more products here
),
// more categories here
),
Then the code that prints it will look like this:
foreach ($arr as $catId => $catInfo) {
// Category ID and details; use other names if I'm wrong
printf("Category: %d (status: %s)\n", $catId, $catInfo['status'] ? 'active' : 'inactive');
foreach ($catInfo['products'] as $prodInfo) {
printf(" %s (ID: %d)\n", $prodInfo['name'], $prodInfo['p_id']);
// etc.
}
}
Use a recursive function:
function printIds($arr) {
foreach ($arr as $key => $val) {
if (is_array($val) && array_key_exists("p_id", $val)) {
echo $val["p_id"]."\n";
} elseif(is_array($val)) {
printIds($val);
}
}
}
Working example:
$arr = [
2764 => [
'status' => 0,
['p_id' => 100],
],
4544 => [
'status' => 0,
['p_id' => 100],
],
['p_id' => 100],
];
function printIds($arr) {
foreach ($arr as $key => $val) {
if (is_array($val) && array_key_exists("p_id", $val)) {
echo $val["p_id"]"\n";
} elseif(is_array($val)) {
printIds($val);
}
}
}
printIds($arr);
The function loops all entries of a given array and echo's them out, if they contain an array with a key named "p_id". If it does find a nested array, then it does loop also all child arrays.
I have a multidimensional array with key value. I want to loop the data in that array but I don't know how.
This is my array:
$myArray= Array
(
'134' => Array
(
'1138' => Array
(
'id' => 1138,
'qty' => 1,
'price' => 4900000,
'name' => 'Pioneer AVH X5850BT Head Unit Double Din 7Inch',
'options' => Array
(
'image' => '865e6ad631fa45d408acfc6f8a8ff008.jpg',
'created_by' => 134
),
'rowid' => 'f9e62f7ce9665a25ff40848744dd83f4',
'subtotal' => 4900000
),
'1003' => Array
(
'id' => 1003,
'qty' => 1,
'price' => 2250000,
'name' => 'Steelmate SW813 Subwoofer Aktif 10 Inch',
'options' => Array
(
'image' => '962df806d5adc7bd0d22666fe996f139.jpg',
'created_by' => 134
),
'rowid' => '7aa455ef597b2906e3895783bd7a5c70',
'subtotal' => 2250000
)
),
'157' => Array
(
'2527' => Array
(
'id' => 2527,
'qty' => 1,
'price' => 2475000,
'name' => 'Rockford Fosgate P165SE Speaker Split 2way Komponen',
'options' => Array
(
'image' => '81027273a2ad59a96aec85ec66ce2704.jpg',
'created_by' => 157
),
'rowid' => 'ed9301accd0d84bd0417609aa80cebc7',
'subtotal' => 2475000
)
)
);
How do I loop / foreach that array?
I guess there is a foreach inside a foreach, but I don't know how to do that.
You can use a recursive function here, so you don't need to worry how deep your array will be.
Something like this:
function read($arr) {
foreach ($arr as $key => $value) {
if (is_array($value)) {
read($a);
}
else {
// You cann access key and value here (for each array)
}
}
}
read($myArray);
Just use another foreach inside your foreach
foreach ($myArray as $key => $value) {
foreach ($value as $subkey => $subvalue) {
if (is_array($subvalue)) {
foreach ($subvalue as $subsubkey => $subsubvalue) {
// .... and so on
}
}
}
}
/* loop across $myArray (listing elements 134 and 157) */
foreach ($myArray as $groupId => $group) {
echo "walking through group $groupId" . PHP_EOL;
/* loop across "groups" 134 and 157 (listing elements 1138, 1003, etc.) */
foreach ($group as $itemId => $item) {
echo "walking through item $itemId" . PHP_EOL;
/* loop each "item" record in key/value pairs */
foreach ($item as $key => $value) {
echo "$key: ";
/* deal with options sub-array */
if (is_array($value)) {
foreach ($value as $option => $optionValue) {
echo " $option: $optionValue" . PHP_EOL;
}
} else {
echo $value . PHP_EOL;
}
}
}
}
I got two associative, multidimensional arrays $arrayOffered and $arraySold. I would like to merge them under certain conditions:
if value of key 'item' from $arrayOffered exists in $arraySold, both elements should be included in array $result. If for 1 element from $arrayOffered there are 3 elements in $arraySold, I should get also 3 elements in $result.
otherwise, element from $arrayOffered should be added into $result.
One element from $arrayOffered can have >1 equivalents in $arraySold. They should be joined in the way shown below.
Input data:
$arrayOffered = array(
0 => array('item' => 'product_1', 'Category' => 'ABC'),
1 => array('item' => 'product_2', 'Category' => 'DEF')
);
$arraySold = array(
0 => array('item' => 'product_1', 'ItemsSold' => '2', 'ItemsReturned' => 1), //arrays in this array can contain up to 30 elements
1 => array('item' => 'product_1', 'ItemsSold' => '1')
);
Desired result:
$desiredResult = array(
0 => array('item' => 'product_1', 'Category' => 'ABC', 'ItemsSold' => '2', 'ItemsReturned' => 1),
1 => array('item' => 'product_1', 'Category' => 'ABC', 'ItemsSold' => '1'),
2 => array('item' => 'product_2', 'Category' => 'DEF')
);
I got stuck on something like:
$result = array();
foreach ($arrayOffered as $keyOffered => $offeredSubArr)
{
$item = $offeredSubArr['item'];
foreach($arraySold as $keySold => $soldSubArr)
{
if(isset($soldSubArr['item']) && $soldSubArr['item'] == $item)
{
$i = 0;
$test = array_merge($offeredSubArr, $soldSubArr);
$result[$i][] = $test;
$i++;
}
else
{
$result[$i][] = $offeredSubArr;
$i++;
}
}
}
Problem:
- output array isn't formatted the way I wanted
- I know I'm not going in the right direction. Can you please give me a hint?
This is an option, since you have this $arrayOffered as a kind of master file I suggest to build a hash with this array and use later on the foreach look for sold array.
$arrayOffered = array(
0 => array('item' => 'product_1', 'Category' => 'ABC'),
1 => array('item' => 'product_2', 'Category' => 'DEF')
);
$arraySold = array(
0 => array('item' => 'product_1', 'ItemsSold' => '2', 'ItemsReturned' => 1), //arrays in this array can contain up to 30 elements
1 => array('item' => 'product_1', 'ItemsSold' => '1')
);
//Build a hash to get the extra properties
$hashArray = array();
foreach ($arrayOffered as $offered) {
$hashArray[$offered['item']]=$offered;
}
$resultArray = array();
foreach ($arraySold as $sold) {
$hashItem = $hashArray[$sold['item']];
// you dont want this sold flag on your final result
unset($hashItem['sold']);
$resultArray[]=array_merge($hashItem,$sold);
$hashArray[$sold['item']]['sold']= true;
}
//Add all the missing hash items
foreach($hashArray as $hashItem){
if(!isset($hashItem['sold'])){
$resultArray[]=$hashItem;
}
}
print_r($resultArray);
Test sample
http://sandbox.onlinephpfunctions.com/code/f48ceb3deb328088209fbaef4f01d8d4430478db
$result = array();
foreach ($arrayOffered as $keyOffered => $offeredSubArr)
{
$item = $offeredSubArr['item'];
foreach($arraySold as $keySold => $soldSubArr)
{ $i = 0;
if(isset($soldSubArr['item']) && $soldSubArr['item'] == $item)
{
$test = array_merge($offeredSubArr, $soldSubArr);
$result[$i][] = $test;
}
else
{
$result[$i][] = $offeredSubArr;
}
$i++;
}
}
$result = $result[0];
echo '<pre>'; print_r($result); die();
Well i will try to follow your logic although there is simpler solutions.
First of all we will need to search in a multidimentional array thats why we will need the followed function from this so thread
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
Next after small changes:
$i you don't need to make it zero on every loop just once so place it outside
unnecessary [] ($result[$i][]) you don't need the empty brackets no reason to create an extra table in the $i row since what you add there, the $test is already table itself
Adding the last loop coz when sth is not in the second table it will be added in your new table in every loop and as far as i get you don't want that kind of duplicates
We have the following code:
$arrayOffered = array(
0 => array('item' => 'product_1', 'Category' => 'ABC'),
1 => array('item' => 'product_2', 'Category' => 'DEF')
);
$arraySold = array(
0 => array('item' => 'product_1', 'ItemsSold' => '2', 'ItemsReturned' => 1), //arrays in this array can contain up to 30 elements
1 => array('item' => 'product_1', 'ItemsSold' => '1')
);
$i = 0;
$result = array();
foreach ($arrayOffered as $keyOffered => $offeredSubArr)
{
$item = $offeredSubArr['item'];
foreach($arraySold as $keySold => $soldSubArr)
{
if(isset($soldSubArr['item']) && $soldSubArr['item'] == $item)
{
$test = array_merge($offeredSubArr, $soldSubArr);
$result[$i] = $test;
$i++;
}
}
}
foreach ($arrayOffered as $value)
{
if (!in_array_r($value['item'], $result))
{
$result[$i] = $value;
$i++;
}
}
print_r($result);
Which as far as i tested gives the wanted result.
the following produces no output, when really it should show a list including Milk, Cheese and Yoghurt. It is probably something really simple, I just can't see it.
<?php
$FoodList=array();
$newArray =array();
echo "<p>";
$Dairy= array(
'a' => 'Milk',
'b' => 'Cheese',
'c' => 'Yoghurt',
);
$Fruit = array(
'd' => 'Apples',
'e' => 'Oranges',
'f' => 'Grapefruit',
);
$GlutenFree = array(
'g' => 'GF Cookies',
'h' => 'GF Pancakes',
'i' => 'GF Bread',
);
$Sweets = array(
'j' => 'Musk Sticks',
'k' => 'Caramels',
'l' => 'Chocolate',
);
if ($_POST['running'] == 'yes')
{
$newArray = array_merge($FoodList, $Dairy);
foreach ($newArray as $key => $value)
{
echo $value;
}
}
echo "<p>";
?>
This may because the FoodList Array does not have anything in it, so I will look into that, but I have a strong feeling it is related to something else.
Your "bug" must be coming from the line, the array merge is fine:
if ($_POST['running'] == 'yes')
foreach($Dairy as $key => $value)
{
echo $value;
}