I have multidimensional array $items and I need to search it and then create new array(s).
This array is generated at the end of check-up in e-shop I'm trying to build, so array can be of random length. I need to create to create new array for every new supplier_id so I can send data to each and every one of them apart.
I already have code for making order but now it just takes all data at once. So in this particular example I'm expecting 3 multidimensional arrays that I can run trough my create_order code.
I know there are many threads talking about multidimensional arrays but none that I can understand enough to apply it in my case. Thanks very much for help.
Here is what $items may look like
array (4)
id => 36
count => 1
product => Nette\Database\Table\ActiveRow #7c60
table private => Nette\Database\Table\Selection #739c
data private => array (3)
product_id => 36
price => 219.0
supplier_id => 3
dataRefreshed private => FALSE
names => array (1)
en => "Product 1" (9)
array (4)
id => 180
count => 1
product => Nette\Database\Table\ActiveRow #938b
table private => Nette\Database\Table\Selection #a5f0
data private => array (3)
product_id => 180
price => 375.0
supplier_id => 4
dataRefreshed private => FALSE
names => array (1)
en => "Product 2" (9)
array (4)
id => 309
count => 1
product => Nette\Database\Table\ActiveRow #4c67
table private => Nette\Database\Table\Selection #8f56
data private => array (3)
product_id => 309
price => 40.0
supplier_id => 5
dataRefreshed private => FALSE
names => array (1)
en => "Product 3" (9)
So after few hours of digging I was amazed how easily it can by done
// searching for all unique supplier_id
$uniqueID = array();
foreach ($items as $item) {
if (!in_array($item['product']['supplier_id'], $uniqueID)) {
array_push($uniqueID, $item['id'] = $item['product']['supplier_id']);
}
}
// visual check of all unique *supplier_id*
dump($uniqueID);
// creation of array where I'm going to insert all necessary data
foreach ($uniqueID as $array) {
$defined_array = [];
// visual check for debugging purposes
dump("start");
// creating multiarray for every unique *supplier_id* and inserting data
foreach ($items as $item) {
if($item['product']['supplier_id'] == $array) {
$defined_array[] = $item;
}
}
// final check of all arrays + debug check for end --
// at the end this block is replaced by *create_order* code
foreach ($defined_array as $array) {
dump($array);
}
dump("end");
}
At the end I hope it will help to someone at least.
Related
I have spent now 2 days figuring out this problem. I'm trying to create voting script which reads .txt file and modifies values inside it. I have problem with foreach part where I try to add +1 in votes of person. 1-5 is id of person, number after | is amount of votes. First output is:
Array
(
[0] => 1|2
[1] => 2|6
[2] => 3|8
[3] => 4|3
[4] => 5|10
and I want it to add just +1 in last number. But if I try to use increment, I get error: "PHP Fatal error: Cannot increment/decrement overloaded objects nor string offsets in..."
foreach ($file_contents as &$id) {
if ($id == 2) {
$id[2]++;
}
}
print_r($file_contents);
I'm still learning PHP and this is weird to me, because just giving "$id[2] = 8" actually modifies that value. Why ++ can't be used? What's way around this?
Array
(
[0] => 1|2
[1] => 2|8
[2] => 3|8
[3] => 4|3
[4] => 5|10
)
Use json instead. It will make your life much easier.
Json is a text string that can be decode in to an array.
Either a indexed array or an associative array. Associative is preferred in this case in my opinion.
$votes = ["1" => 2, "2" => 6, "3" => 8, "4" => 3, "5" => 10];
// Above is an associative array with the same data as your example.
// The key is the id and the value is the votes.
// To read it from the file use:
// $votes = json_decode(file_get_contents("file.txt"));
$inputVote = 2; // someone voted on person 2.
if(!isset($votes[$inputVote])) $votes[$inputVote] = 0; // if someone voted on a person not already in the array, add the person to the array.
$votes[$inputVote]++; // increments the votes on person 2.
file_put_contents("file.txt", json_encode($votes));
This question already has an answer here:
How right replace value element in array?
(1 answer)
Closed 5 years ago.
I am using WordPress and have a custom post type setup with a set number of options, with the basic breakdown being something like this:
30" Round Table
Buffet
Cocktail
Dessert
Banquet Table
Buffet
Gift
DJ Table
I am trying to collect all items into a grouped collection, for use with <optgroup /> to show all tables under Buffet, all under Cocktail, etc. like so:
Buffet
30" Round Table
Banquet Table
Cocktail
Banquet Table
[and so on]
The PHP issue I'm running into is I have a master array that has all the types (buffet, cocktail, etc.) along with an (initially) empty array element called tables for me to add all the tables that support that specific type. Retrieving the options from ACF works fine, as does retrieving the individual posts from WordPress, so this is strictly a packaging issue to kick back as JSON. Here is a code example:
//gets the field associated with the different table types (Buffet, Cocktail, etc.)
$field = get_field_object('field_577ff065e6699');
$list = array();
//create the base array
foreach ($field["choices"] as $type) {
$list[] = array
(
"type" => $type, //Buffet, Cocktail, etc.
"tables" => array() //placeholder to add WP items
);
}
//now get all tables
$tablesQuery = new WP_Query( array( 'post_type' => 'table', 'posts_per_page' => -1, 'order' => 'ASC' ) );
//loop through and add the table(s) to their categories
while ( $tablesQuery->have_posts() ) : $tablesQuery->the_post();
//gets the types supported by this table
$tableTypes = get_field('options');
//individual types
foreach ($tableTypes as $tableType) {
//all types
foreach ($list as $supportedType) {
//see if there is a match and add it
if ($tableType == $supportedType["type"]) {
//add to the array since it matches
$table = array
(
"name" => get_the_title(),
"sqft" => (int)get_field('square_footage'),
"seats" => (int)get_field('seats')
);
array_push($supportedType["tables"], $table);
//shows the single table above, but nothing prior
print_r($supportedType);
}
}
}
endwhile;
wp_reset_postdata();
//all "tables" arrays are empty here
var_dump($list);
The output of print_r($supportedType) above ends up showing all data, however the tables entry is always only one element when it should be multiple:
Array
(
[type] => Buffet
[tables] => Array
(
[0] => Array
(
[name] => 30” Round Bistro/Cocktail Table
[sqft] => 42
[seats] => 2
)
)
)
Array
(
[type] => Cake
[tables] => Array
(
[0] => Array
(
[name] => 30” Round Bistro/Cocktail Table
[sqft] => 42
[seats] => 2
)
)
)
[.. snip ..]
Finally, when I do the var_dump($list) at the end, all of the types show up but their associated tables arrays are all empty:
array(11) {
[0]=>
array(2) {
["type"]=>
string(6) "Buffet"
["tables"]=>
array(0) {
}
}
[1]=>
array(2) {
["type"]=>
string(4) "Cake"
["tables"]=>
array(0) {
}
}
This has me completely lost, even though it has to be something incredibly basic that I'm missing. Any ideas why tables is empty, despite using array_push on the looped item? I also tried $supportedType["tables"][] = $table, but that has the same effect.
I think you're working with a copy of the array inside this foreach: foreach ($list as $supportedType) {
Try changing it to
foreach ($list as $key => $supportedType) {
...
// this operates on the copy
// array_push($supportedType["tables"], $table);
// operate on the original instead
array_push($list[$key]["tables"], $table);
...
}
I have and array that is being produced from a webservice.
Array (
[TPA_Extensions] => Array (
[TPARoomDetail] => Array (
[GuestCounts] => Array (
[GuestCount] => Array (
[!AgeQualifyingCode] => 10
[!Count] => 1
)
)
[!Occupancy] => Single
[!OccupancyCode] => SGL
)
)
[!IsRoom] => true
[!Quantity] => 1
[!RoomType] => Palace Gold Club Room
[!RoomTypeCode] => PGC
)
My foreach loop is as below
foreach ($roomType["TPA_Extensions"]["TPARoomDetail"]["GuestCounts"]["GuestCount"] as $guestcount) {
echo "guest count1->";print_r($guestcount);
echo "guest count2->"; print_r($roomType["TPA_Extensions"]["TPARoomDetail"]["GuestCounts"]["GuestCount"]);
}
The output i get is
guest
count1->10 guest count2->Array ( [!AgeQualifyingCode] => 10 [!Count] => 1 )
guest count1 should have been an array
Array ( [!AgeQualifyingCode] => 10 [!Count] => 1 ) but it comes as an int 10 ..
why is that so ..?
Your output is correct, $guestcount holds the number '10',
where $roomType["TPA_Extensions"]["TPARoomDetail"]["GuestCounts"]["GuestCount"]
hold an array.
this is your loop:
foreach ($roomType["TPA_Extensions"]["TPARoomDetail"]["GuestCounts"]["GuestCount"] as $guestcount) {
echo "guest count1->";print_r($guestcount);
echo "guest count2->"; print_r($roomType["TPA_Extensions"]["TPARoomDetail"]["GuestCounts"]["GuestCount"]);
}
ths loop will run 2 times, because that's the number of childs in GuestCount array.
it will be '10', then '1', exactly reflecting the structure of your array:
[!AgeQualifyingCode] => 10
[!Count] => 1
Theres nothing wrong in the code as 1st index holds integer value and 2nd index holds array. However your method of accessing array value are very complicated and doesn't looks good. You an access the array values and keys in more effective manner as follows.
1)Create a method that takes path of the array you want to access
For example According to your code if I want to access AgeQualifyingCode key than I have to write $roomType["TPA_Extensions"]["TPARoomDetail"]["GuestCounts"]["GuestCount"]["AgeQualifyingCode"].
This doesn't looks good, wouldn't it be great if you just have to pass the path of key you want to access the value to.
For example: /TPA_Extensions/TPARoomDetail/GuestCounts/GuestCount/AgeQualifyingCode
You just have to define a function that takes the path of the key, and will return value for that key
<?php
function path($path=null){
if($path){
$array = $theNameOfOriginalArray
$path = explode('/',$path);
foreach($path as $sub){
if(isset($array[$sub])){
$array = $array[$sub];
}
}
return $array;
}
}
$value = path('TPA_Extensions/TPARoomDetail/GuestCounts/GuestCount/AgeQualifyingCode');
//will return 10
?>
Well I'm relatively new to the use of PHP arrays and I have the follow array I need to loop through this array 2280 and 2307 are the identifiers.
I'm find it hard trying to come up with a foreach() that collects all the data.
Array
(
[2280] => Array
(
[0] => http://deals.com.au//uploads/deal_image/2706.jpg
[1] => Yuan's Massage and Beauty
[2] => Get Hair Free in CBD! Only $99 for SIX MONTHS worth of the latest in IPL Permanent Hair Reduction. Choose which area you want treated! Valued at $900 from Yuan's Massage and Beauty in the Heart of Melbourne's CBD. Limited vouchers available
[3] => 99
[4] => 900
[5] => 801
[6] => http://deals.com.au/1827
)
[2307] => Array
(
[0] => http://deals.com.au//uploads/deal_image/2683.jpg
[1] => Name Necklace Australia
[2] => Style yourself like SJP! Only $29 for a STERLING Silver Name Necklace plus get FREE delivery! Valued at $75 with NameNecklace.com.au
[3] => 29
[4] => 75
[5] => 46
[6] => http://deals.com.au/Melbourne
)
)
Your array snippet
$array = array( // foreach ($array as $k=>$subarray)
'2280' /* this is your $k */ =>
array( /* and this is your $subarray */
'http://deals.com.au//uploads/deal_image/2706.jpg',
And now you get data you need (you had to use nested foreach since values of your array are arrays):
foreach ($array as $k=>$subarray) {
foreach ($subarray as $data) {
echo $data;//of subarray
}
}
UPDATE
The OPs comment quistion on my answer:
what if I wanted to be selective rather than get a massive data dump.
if I echo $data how do I access specific rows?
Well, in most cases you should associate keys and data in your array (we call it associative array in PHP).
Example 1:
$hex_colors = array('FF0000', '00FF00' '0000FF');
Values are not assoiated with correspondent keys. PHP will assign 0,1,2... keys to arrays elements itself. In this case you would get green color's heximal value using auto-assigned by PHP 1 key: echo $hex_colors[1]; // 00FF00 and of course you should know it for sure. Usually this approach is used when you have strict data structure like array(red, green, bluee), but in most cases you better use the following approach:
Example 2:
$hex_colors = array('red'=>'FF0000', 'green'=>'00FF00' 'blue'=>'0000FF');
heximal colors representations are associated with appropriate keys echo $hex_colors['green']; // 00FF00
If your array was:
$array = array(
'2280' => array(
'image_url' => 'http://deals.com.au//uploads/deal_image/2706.jpg',
'product_name' => 'Yuan\'s Massage and Beauty',
'description' => 'Get Hair Free in CBD! Only $99 for SIX MONTHS worth of the latest in IPL Permanent Hair Reduction. Choose which area you want treated! Valued at $900 from Yuan's Massage and Beauty in the Heart of Melbourne's CBD. Limited vouchers available',
'price' => 99,
'weight_brutto' => 900,
'weight_netto' => 801,
'dealer_store' => 'http://deals.com.au/1827',
...
You would be able to access data using, let's call it "human-readable" keys:
foreach ($array as $id=>$product) {
echo 'Buy '.$product['name'].'';
echo '<img class="product_thumbnail" src="'.$product['image_url'].'" />';
echo 'Description: '.$product['description'];
echo 'The price is '.number_format($product['price']);
...
}
It is well-suited for reading rows from database, for example:
while ($data = mysql_fetch_array($query_result_link, MYSQL_ASSOC)) {
// MYSQL_ASSOC flag is not necessary
// PHP will use this flag by default for mysql_fetch_array function
// keys of $data will be correspondent columns names returned by mysql query
echo $data['id'];
echo $data['title'];
...
}
Continue learning PHP and you will find many more situations when it's more convenient to associate keys and values.
foreach ($arr1 as $key1 => $value1) {
//$key1==2280; $value1 is the array
foreach ($value1 as $key2 => $value2) {
//$key2==0;$value2="http://deals.com.au//uploads/deal_image/2706.jpg"
}
}
I have two arrays:
$course = Array ( [6] => 24 [0] => 20 [1] => 14 ) // etc
With the key being the link to the next array:
Array (
[0] => Array ( [course_id] => 1 [course_name] => Appetizer )
[1] => Array ( [course_id] => 2 [course_name] => Breakfast )
) //etc
I basically want to add the course_name to the first array on course_id = keyso that it I can print out '1', 'Appetizer', '14'
Sorry if Ive explained this badly but its late and merging arrays frazzles my brain at this time!
5.3's closures combined with the various native array iteration functions make this in to a pretty painless process:
<?php
// where $key is a course_id and $value is the associated course's next course
$nextCourse = array(6 => 24, 0 => 20, 1 => 14);
// course definitions
$courses = array(
0 => array("course_id" => 1, "course_name" => 'Appetizer'),
1 => array("course_id" => 2, "course_name" => 'Breakfast')
);
// loop through and add a next_course reference if one exists in $nextCourse map
foreach($courses as &$course) {
if (isset($nextCourse[$course["course_id"]])) {
$course["next_course"] = $nextCourse[$course["course_id"]];
}
}
// $courses is now the same as the var dump at the end
/**
* A bit of 5.3 proselytism with native array functions and closures, which is
* an overly complex answer for this particular question, but a powerful pattern.
*
* Here we're going to iterate through the courses array by reference and
* make use of a closure to add the next course value, if it exists
*
* array_walk iterates over the $courses array, passing each entry in
* the array as $course into the enclosed function. The parameter is
* marked as pass-by-reference, so you'll get the modifiable array instead
* of just a copy (a la pass-by-value). The enclosure function requires
* the 'use' keyword for bringing external variables in to scope.
*/
array_walk($courses, function(&$course) use ($nextCourse) {
/**
* We check to see if the current $course's course_id is a key in the
* nextCourse link mapping, and if it is we take the link mapping
* value and store it with $course as its next_course
*/
if (isset($nextCourse[$course["course_id"]])) {
$course["next_course"] = $nextCourse[$course["course_id"]];
}
});
var_dump($courses);
/**
Output:
array(2) {
[0]=>
array(3) {
["course_id"]=>
int(1)
["course_name"]=>
string(9) "Appetizer"
["next_course"]=>
int(14)
}
[1]=>
array(2) {
["course_id"]=>
int(2)
["course_name"]=>
string(9) "Breakfast"
}
}
*/