Php array in a foreach loop - php

I have been trying to create a Multidimensional array from an already existing array. The reason I am doing this is so I can separate the super array into a more categorized version so that later on I can run foreach on just those categories in another script.
This is a snippet of code // Please read comments :)
$and = array();
if($this-> input-> post('and')) // This is the super array and[] from a previous input field
{
if(preg_grep("/reason_/", $this-> input-> post('and'))) // Search for the reason_
{
foreach($this-> input-> post('and') as $value) // if reason_ is present
{
$and['reason_and'] .= end(explode('_', $value)) . ' , '; // Remove everything before and including _ so then i would get only values like 1, 2, 3, 4, and then concatenate them to the index
}
}
if(preg_grep("/status_/", $this-> input-> post('and'))) // Search for status
{
foreach($this-> input-> post('and') as $value) // If it is in the super array
{
$and['status_and'] .= end(explode('_', $value)) . ' , '; // Remove everything before and including _ so then I would get values again like 1,2,3,4,5 and then concatenate them to the index
}
}
}
This approach is not giving me expected outcome however, I am getting a big string like so :
array(2) { ["reason_and"]=> string(24) "2 , 3 , 4 , 3 , 4 , 5 , "
["status_and"]=> string(24) "2 , 3 , 4 , 3 , 4 , 5 , "
So to my knowledge (which is limited) when I try to do a foreach over the array
[reason_and]
I only get one loop since the array ["reason_and] only has one value (the 24 character string?). Is it possible to have the reason_and have a value for each of the numbers?
Is this even possible? I'm quite confused.
I've referred to this question for reference but I still do not get a outcome that I can work with. Thanks in advance.

This
$and['reason_and'] .= end(explode('_', $value)) . ' , ';
^^^^----
should be
$and['reason_and'][] = end(explode('_', $value)) . ' , ';
^^--
which turns it into an "array push" operation, not a string concatenation. Then 'reason_and' will be an array, and you foreach over it.

first of all preg_grep returns an array with matched values, so
$andArray = $this-> input-> post('and'); // This is the super array and[] from a previous input field
if($andArray) {
$reason = preg_grep("/reason_/", $andArray); // Search for the reason_
if($reason) { // if reason_ is present
foreach($reason as $value) {
$and['reason_and'] .= end(explode('_', $value)) . ' , '; // Remove everything before and including _ so then i would get only values like 1, 2, 3, 4, and then concatenate them to the index
}
}
$status = preg_grep("/status_/", $andArray); // Search for status
if($status) {
foreach($status as $value){ // If it is in the super array
$and['status_and'] .= end(explode('_', $value)) . ' , '; // Remove everything before and including _ so then I would get values again like 1,2,3,4,5 and then concatenate them to the index
}
}
}
Or if you need result as array, then remove ' , ' and replace dot with [];

Related

php multi level foreach loop remove last comma from loop

hii i have 2 level foreach loop like this and i want to remove last comma from each loop ,
/* Here is the mysql query */
foreach($loop1 as $val1){
$showvalone = $val1['data1'];
echo "[".$showvalone;
/* Here is the second MySQL query connected with 1st query */
foreach($loop2 as $val2){
$showvaltwo[] = $val2['data2'];
}
echo implode(",",$showvaltwo);
echo "] , ";
}
output of this program :
[ 1
one ,
two ,
three
],
[ 2
one ,
two ,
three
],
And i want like this
[ 1
one ,
two ,
three
],
[ 2
one ,
two ,
three
]
i am already use implode , trim but is remove only one loop not remove second .
sol me my problem , thanks .
You can turn the problem around and add the ',' to the start of the next output. There is no need to remove it afterwards.
However you don't want the comma for the first output.
$addComma = ''; // should be empty for the first lines.
foreach($loop1 as $val1){
$showvalone = $val1['data1'];
echo $addComma."[".$showvalone;
/* Here is the second MySQL query connected with 1st query */
foreach($loop2 as $val2){
$showvaltwo[] = $val2['data2'];
}
echo implode(",",$showvaltwo);
echo "]";
$addComma = " , "; // any lines following will finish off this output
}
Rather than output the information directly you could put it in to a variable as a string. This will allow you to rtrim the last comma after the loop, then echo the information.
// Declare variable to hold the string of information.
$values = "";
/* Here is the mysql query */
foreach($loop1 as $val1)
{
$showvalone = $val1['data1'];
$values .= "[".$showvalone;
/* Here is the second MySQL query connected with 1st query */
foreach($loop2 as $val2)
{
$showvaltwo[] = $val2['data2'];
}
$values .= implode(",",$showvaltwo);
$values .= "] , ";
}
// Remove the last comma and spaces from the string.
$values = rtrim($values, ' , ');
// Output the information.
echo $values;
I have my own version in removing "," at the end and instead of adding a "."
$numbers = array(4,8,15,16,23,42);
/* defining first the "." in the last sentence instead of ",". In preparation for the foreach loop */
$last_key = end($ages);
// calling the arrays with "," for each array.
foreach ($ages as $key) :
if ($key === $last_key) {
continue; // here's the "," ends and last number deleted.
}
echo $key . ", ";
endforeach;
echo end($ages) . '.' ; // adding the "." on the last array

removing "The " from array values to order alphabetically

I have an array in which every value starts with a name of a venue. Some venues have a "The " in front of them which I want to remove so that when I sort() the array I don't end up with all the "The ..." venues at the "T".
I wrote this:
function remove_The($array) {
global $all_venue_listings;
// remove the "The" from the listings...
foreach($all_venue_listings as $v) {
if ( substr($v, 0, 4) === "The " || substr($v, 0, 4) === "the " || substr($v, 0, 4) === "THE " ) {
$v = preg_replace("/The /i","",$v);
}
}
return $all_venue_listings;
}
But that doesn't seem to put the changed values back into the array. How can I operate on the array in the foreach loop so that what I change goes back into the original array?
I tried replacing the preg_replace line with this:
$all_venue_listings[] = preg_replace("/The /i","",$v);
But that just creates a duplicate entry in the array (one with "The " and one without).
Two options.
1) Use a reference and update the element directly (note the &):
foreach($all_venue_listings as &$v) {
...
$v = ...
2) Use a key and update the original array:
foreach($all_venue_listings as $key => $v) {
...
$all_venue_listings[$key] = ...
Either will work. I prefer #1

Retrieving values crossing arrays gives unlogic result

In Drupal context, while printing checked exposed filters in a somehow standard code snippet, I can't print more than one value, and I can't find the missing logic of my foreach loop :
<?php
foreach ($exposed_filters as $filter => $value) {
if ($filter == 'foo') {
$field = field_info_field('field_foo');
$allowed_values = list_allowed_values($field);
//returns an array with 14 string values & numeric keys
//e.g array(0=>'bla', 1=>'bar', 2=>'xx', 3=>'yy')
$h = explode(',', $value);//returns checked ids of foo filter e.g array(0 => 2, 1=>3)
$exp_heb = '';
foreach ($h as $k=>$v) {
$exp_heb .= $allowed_values[$v] . ', ';
}
$exp_heb = substr($exp_heb, 0, -2);
print $exp_heb;
}
}
?>
Should return : xx, yy but I get xx,,
I checked step by step printing out my arrays, values... everything's looks fine but result is wrong. Do I need a rest ???
This is dpm($allowed_values) output
May be this line cuts your output?
$exp_heb = substr($exp_heb, 0, -2);
I got it working. I have to get the integer value of my variable, before passing it as a key :
foreach ($h as $k=>$v) {
$exp_heb .= $allowed_values[intval($v)] . ', ';
}
For a reason I would be glad to be taught, even if it's always an id, and prints out a number, first time it's passed as integer, but then not.

The word Array is displayed as the first item

I am getting the values from an array this is taken from jQuery.serialize() just an input field. I then send then form data to a sendMail page.
Display the results in an email and the word Array is the first word then the value inputted follows, the rest of the data displayed is ok.
I have four arrays and in front of each the word Array appears.
$qty = $_POST['qty'];
foreach($qty as $value)
{
$qty .= $value . "<br>";
}
$desc = $_POST['description'];
foreach($desc as $value)
{
$desc .= $value . "<br>";
}
$options = $_POST['options'];
foreach($options as $value)
{
$options .= $value . "<br>";
}
$price = $_POST['price'];
foreach($price as $value)
{
$price .= $value . "<br>";
}
input would be qty: 1, Desc: description, options: small, price: 1.99
output is Array 1, Array description, Array options, Array small.
only on the first line the rest of the lines are ok.
You are concatenating to the POST array you should do this instead:
$qty = $_POST['qty'];
foreach($qty as $value)
{
$qty2 .= $value . "<br>";
}
echo $qty2;
Each part of your code contain the inconsistency of both assuming you have an array as POST-data and then assigning it as an string.
$possible_array = $_POST['possible_array'];
foreach($possible_array as $value)
{
$possible_array .= $value . "<br>"; // < - here you use $possible_array as a string
}
One way forward should be to assign the string value to another string:
$possible_array = $_POST['possible_array'];
foreach($possible_array as $value)
{
$string .= $value . "<br>"; // < - change to a new string
}
However it seem not probable that you actually have POST-data in arrays here I guess you send different items which each have the properties qty, description etc
I think you would like to use a solution where you iterate (foreach) on product info as an two-dimensional array, like $_POST['products']['qty'] where products is an array. But to help you further you would need to include your POST-data to see how its structured/serialized.
That happens because you append the value of each array to the array itself. Due to the value being a string the result also becomes a string. So the array will implicitly be casted to a string which results in the word "Array".
Possible solution:
$qtyList = implode('<br>' , $_POST['qty']);

Add commas to items and with "and" near the end in PHP [duplicate]

This question already has answers here:
Implode an array with ", " and add "and " before the last item
(16 answers)
Closed 10 months ago.
I want to add a comma to every item except the last one. The last one must have "and".
Item 1, Item 2 and Item 3
But items can be from 1 +
So if one item:
Item 1
If two items:
Item 1 and Item 2
If three items:
Item 1, Item 2 and Item 3
If four items:
Item 1, Item 2, Item 3 and Item 4
etc, etc.
Here’s a function for that; just pass the array.
function make_list($items) {
$count = count($items);
if ($count === 0) {
return '';
}
if ($count === 1) {
return $items[0];
}
return implode(', ', array_slice($items, 0, -1)) . ' and ' . end($items);
}
Demo
minitech's solution on the outset is elegant, except for one small issue, his output will result in:
var_dump(makeList(array('a', 'b', 'c'))); //Outputs a, b and c
But the proper formatting of this list (up for debate) should be; a, b, and c. With his implementation the next to last attribute will never have ',' appended to it, because the array slice is treating it as the last element of the array, when it is passed to implode().
Here is an implementation I had, and properly (again, up for debate) formats the list:
class Array_Package
{
public static function toList(array $array, $conjunction = null)
{
if (is_null($conjunction)) {
return implode(', ', $array);
}
$arrayCount = count($array);
switch ($arrayCount) {
case 1:
return $array[0];
break;
case 2:
return $array[0] . ' ' . $conjunction . ' ' . $array[1];
}
// 0-index array, so minus one from count to access the
// last element of the array directly, and prepend with
// conjunction
$array[($arrayCount - 1)] = $conjunction . ' ' . end($array);
// Now we can let implode naturally wrap elements with ','
// Space is important after the comma, so the list isn't scrunched up
return implode(', ', $array);
}
}
// You can make the following calls
// Minitech's function
var_dump(makeList(array('a', 'b', 'c')));
// string(10) "a, b and c"
var_dump(Array_Package::toList(array('a', 'b', 'c')));
// string(7) "a, b, c"
var_dump(Array_Package::toList(array('a', 'b', 'c'), 'and'));
string(11) "a, b, and c"
var_dump(Array_Package::toList(array('a', 'b', 'c'), 'or'));
string(10) "a, b, or c"
Nothing against the other solution, just wanted to raise this point.
Here's a variant that has an option to support the controversial Oxford Comma and takes a parameter for the conjunction (and/or). Note the extra check for two items; not even Oxford supporters use a comma in this case.
function conjoinList($items, $conjunction='and', $oxford=false) {
$count = count($items);
if ($count === 0){
return '';
} elseif ($count === 1){
return $items[0];
} elseif ($oxford && ($count === 2)){
$oxford = false;
}
return implode(', ', array_slice($items, 0, -1)) . ($oxford? ', ': ' ') . $conjunction . ' ' . end($items);
}
You can implode the X - 1 items with a comma and add the last one with "and".
You can do it like this:
$items = array("Item 1", "Item 2", "Item 3", "Item 4");
$item = glueItems($items);
function glueItems($items) {
if (count($items) == 1) {
$item = implode(", ", $items);
} elseif (count($items) > 1) {
$last_item = array_pop($items);
$item = implode(", ", $items) . ' and ' . $last_item;
} else {
$item = '';
}
return $item;
}
echo $item;
My function, based on others here, that I feel like is more streamlined. Also always adds in the Oxford comma because there really is no "controversy" or debate about whether it's correct or not to use.
//feed in an array of words to turn it into a written list.
//['bacon'] turn into just 'bacon'
//['bacon','eggs'] turns into 'bacon and eggs'
//['bacon','eggs','ham'] turns into 'bacon, eggs, and ham'
function writtenList($items) {
//nothing, or not an array? be done with this
if (!$items || !is_array($items)) return '';
//list only one or two items long, this implosion should work fine
if (count($items)<=2) {
return implode(' and ',$items);
//else take off the last item, implode the rest with just a comma and the remaining item
} else {
$last_item = array_pop($items);
return implode(", ",$items).', and '.$last_item;
}
}
Well if it is an array just use implode(...)
Example:
$items = array("Item 1", "Item 2", "Item 3", "Item 4");
$items[count($items) - 1] = "and " . $items[count($items) - 1];
$items_string = implode(", ", $items);
echo $items_string;
Demo: http://codepad.viper-7.com/k7xISG

Categories