This question already has answers here:
How can I loop through two arrays at once? [duplicate]
(2 answers)
Closed 6 years ago.
I want to generate a selectbox using two arrays, one containing option-value and option-name and one containing data-value for the option
For example:
"arra1" => array("1" => "orange", "2" => "banana", "3" => "apple"),
"data-array" => array("first" , "second" , "third"),
and result must be
foreach( ??? ) {
<option value=1 data-value="first">orange</option>
<option value=2 data-value="second">banana</option>
<option value=3 data-value="third">apple</option>
}
Suggestions? Thanks
Use PHP's array_values function to get both array with same indexing, then do the foreach:
$data = [
"arra1" => array("1" => "orange", "2" => "banana", "3" => "apple"),
"data-array" => array("first" , "second" , "third")
];
$labels = array_values($data["arra1"]);
$values = array_values($data["data-array"]);
foreach($labels as $index => $value) {
$optionValue = $index+1;
echo "<option value={$optionValue} data-value='{$values[$index]}'>{$labels[$index]}</option>";
}
It actually uses one array ($key+1) is the key value of $array_1 if you are starting array key value from 1 not 0, This is a suggestion:
<?php
$arry_1 = array("1" => "orange", "2" => "banana", "3" => "apple");
$data_array = array("first" , "second" , "third");
foreach ($data_array as $key => $value) {
echo '<option value="'.($key+1).'" data-value="'.$value.'">orange</option>';
}
?>
You could keep this more simplistic by doing the following:
<?php
foreach ($array as $index => $title)
{
echo "<option data-value='" . $data[$index] . "'>$title</option>";
}
?>
i think you can achieve this using one associative array like below-
//you can construct associative array like this
$array = array("first"=>"orange","second"=>"banana","third"=>"apple");
$count =1;
foreach($array as $key=>$val)
{
echo '<option value='.$count.' data-value="'.$key.'"'.'>'.$val.'</option';
$count++;
}
if you want to use two arrays as given in your question then-
$arr = ["arra1" => array("1" => "orange", "2" => "banana", "3" => "apple"),
"data-array" => array("first" , "second" , "third"),];
for($i=1 ; $i<=count($arr['arra1']);$i++)
{
echo '<option value='.$i.' data-value="'.$arr['data-array'][$i-1].'">'.$arr['arra1']["$i"].'</option>';
}
This can be helpful to get your desired output :
$arra1 = array("1" => "orange", "2" => "banana", "3" => "apple");
$data_array = array("first" , "second" , "third");
echo "<select>";
foreach ($arra1 as $key => $value) {
echo '<option value="'.($key).'" data-value="'.$data_array[$key-1].'">'.$value.'</option>';
}
echo "</select>";
Read about array_map. You can supply any number of arrays to it and traverse them kinda in parallel:
$options = array_map(function ($key, $value, $datum) {
return "<option value=\"$key\" data-value=\"$datum\">$value</option>";
}, array_keys($arry_1), $arry_1, $data_array);
Here is working demo.
Pay attention that in order to pass keys along with values I have used array_keys function.
Related
I have an array thusly
$main_array = [
["image" => "james.jpg", "name" => "james", "tag" => "spacey, wavy"],
["image" => "ned.jpg", "name" => "ned", "tag" => "bright"]
["image" => "helen.jpg", "name" => "helen", "tag" => "wavy, bright"]
]
I use a foreach to echo some HTML based on the value of tag. Something like this
foreach($main_array as $key => $array) {
if ($array['tag'] == "bright") {
echo '<p>'.$array['name'].' '.$array['image'].' '.$array['tag'].'</p>';
}
}
This only outputs "ned" as matching the tag "bright". But it should output "helen" too. Similarly:
foreach($main_array as $key => $array) {
if ($array['tag'] == "wavy") {
echo '<p>'.$array['name'].' '.$array['image'].' '.$array['tag'].'</p>';
}
}
Should output "james" and "helen". What kind of function do I need to achieve the desired result?
When checking an item in a list of items, you can use explode() to split it into parts (I've used split by ", " as each item seems to have a space as well) and then use in_array() to check if it is in the list...
if (in_array("bright", explode( ", ", $array['tag']))) {
You cant do it directly, because it return key with values in string. Below are the working code.
<?php
$main_array = [
["image" => "james.jpg", "name" => "james", "tag" => "spacey, wavy"],
["image" => "ned.jpg", "name" => "ned", "tag" => "bright"],
["image" => "helen.jpg", "name" => "helen", "tag" => "wavy, bright"]
];
foreach($main_array as $key => $array) {
$str_arr = explode (", ", $array['tag']);
foreach ($str_arr as $key2 => $array2) {
if ($array2 == "wavy") {
echo '<p>'.$array['name'].' '.$array['image'].' '.$array['tag'].'</p>';
}
}
}
?>
I have this array written below, and I know it isnt pretty, sorry. I come to this array structure as it is the only way I could think of when dealing with my post request.
$_POST = array("person" => array(
[1] => array("id" => 1, "name" => "bob"),
[2] => array("id" => 2, "name" => "jim")
)
);
I want to be able to pick "name" from certain "id", so below code is what I came up with. In the example below, if person["id"] is equal to 1, retrieve its "name" which is "bob".
foreach ($_POST as $dataSet) {
foreach ($dataSet as $person) {
foreach ($person as $field => $value) {
if ($person["id"] == 1) {
echo $person["name"];
}
}
}
}
The problem I am having is as I execute the code.
the result is bobbob,
it seems like the code looped the if statement twice (same as the number of elements in the person array). I know if I put break into the code, then it will solve it, but anyone know why it looped twice? Maybe this will deepen my foreach and array understanding.
There is no need to have third nested loop. Hope this one will be helpful.
Problem: In the third loop you were iterating over Persons: array("id" => 1, "name" => "bob") which have two keys. and you are checking only single static key $person["id"], that's why it was printing twice.
Solution 1:
Try this code snippet here
<?php
ini_set('display_errors', 1);
$POSTData = array("person" => array(
1 => array("id" => 1, "name" => "bob"),
2 => array("id" => 2, "name" => "jim")
)
);
foreach ($POSTData as $dataSet)
{
foreach ($dataSet as $person)
{
if ($person["id"] == 1)
{
echo $person["name"];
}
}
}
Solution 2:
Alternatively you can try this single line solution.
Try this code snippet here
echo array_column($POSTData["person"],"name","id")[1];//here 1 is the `id` you want.
You must have seen the other answers, and they have already said that you dont need the 3rd loop. but still if you want to keep the third loop.
you can use this code.
foreach ($_POST as $dataSet) {
foreach ($dataSet as $person) {
foreach ($person as $field => $value) {
if($value == 1){
echo $person['name'];
}
}
}
}
No need of third foreach
<?php
$mainArr = array("person" => array(
1 => array("id" => 1, "name" => "bob"),
2 => array("id" => 2, "name" => "jim")
)
);
foreach ($mainArr as $dataSet) {
foreach ($dataSet as $person) {
if ($person["id"] == 1) {
echo $person["name"];
break;
}
}
}
?>
Live demo : https://eval.in/855386
Although it's unclear why you need to do a POST in this fashion, here's how to get "bob" only once:
<?php
$_POST = array("person" => array(
1 => array("id" => 1, "name" => "bob"),
2 => array("id" => 2, "name" => "jim")
)
);
$arr = array_pop($_POST);
foreach($arr as $a) {
if ($a["id"] == 1) {
echo $a["name"];
}
}
Array_pop() is useful for removing the first element of the array whose value is an array itself which looks like this:
array(2) {
[1]=>
array(2) {
["id"]=>
int(1)
["name"]=>
string(3) "bob"
}
[2]=>
array(2) {
["id"]=>
int(2)
["name"]=>
string(3) "jim"
}
}
When the if conditional evaluates as true which occurs only once then the name "bob" displays.
See live code.
Alternatively, you could use a couple of loops as follows:
foreach ($_POST["person"] as $data) {
foreach ($data as $value) {
if ( $value == 1) {
echo $data["name"],"\n";
}
}
}
See demo
As you mentioned, I want to be able to pick name from certain id, : No need of nested looping for that. You can do like this using array_column and array_search :
$data = array("person" => array(
1 => array("id" => 1, "name" => "bob"),
2 => array("id" => 2, "name" => "jim")
)
);
// 1 is id you want to search for
$key = array_search(1, array_column($data['person'], 'id'));
echo $data['person'][$key + 1]['name']; // $key + 1 as you have started array with 1
Output:
bob
with foreach:
foreach ($data as $dataValue) {
foreach ($dataValue as $person) {
if ($person['id'] === 1) {
echo $person["name"];
}
}
}
How Do I access the innermost array? the grade is giving me a Notice: Array to string conversion in /scripts/array.php on line 34
grade: Array
$data = array();
$data[0] = 78;
$data[1] = 34;
$data[2] = 87;
$student = array(0 => array(
"Stdno" => "212",
"name" => "Lorem Ipsum",
"subject" => "Networking",
"grade" => $data
),
1 => array(
"Stdno" => "212",
"name" => "Jimmy Shu",
"subject" => "Informatics",
"grade" => $data
),
2 => array(
"Stdno" => "212",
"name" => "Amet Dolor",
"subject" => "Discrete Combinatorics",
"grade" => $data
)
);
foreach ($student as $key => $value) {
foreach ($value as $key => $value) {
echo "<b>{$key}</b>: {$value}";
echo "<br />";
}
echo "<br />";
}
First of all, you should really not use $key and $value again (in fact, I thought foreach ($value as $key=>$value) didn't work).
Assuming you want to echo the $data element at the same position than in your $student array (i.e. echo $data[0] for $student[0]), you should use the first key :
foreach ($student as $key => $value) {
foreach ($value as $key2 => $value2) {
echo "<b>{$key2}</b>: ";
if ($key2 == 'grade')
echo $value2[$key];
else
echo $value2;
echo "<br />";
}
echo "<br />";
}
First, just a comment please avoid using same keys on foreach. like in your $value.
To fix your issue, it clearly says, it's an array but you try to echo it, you could try to use this instead.
echo "<b>{$key}</b>: " . json_encode($value);
As stated by #roberto06 you should avoid using same variables for cycles that are nested. Those variables will be overwriten by new values.
To the question:
You could check wether $value is string or array
is_array($val) || is_string($val)
based on result you could write another foreach cycle or print string.
in your second foreach you are foreaching this array:
array(
"Stdno" => "212",
"name" => "Lorem Ipsum",
"subject" => "Networking",
"grade" => $data
)
so the (second) $key will be "Stdno", "name", "subject", "grade"
and values will be "212", "Lorem Ipsum", "Networking" (those are strings) and $data (this is array)
to print this array, you need to create new foreach and use it only when $key == "grade" or use implode on it:
if($key == "grade"){
$i = implode(', ', $value);
//print or something
}
Im trying to build a json array in php with this structure:
[{"id":"name last name",
"id":"name last name",
"id":"name last name"
}]
where the id key is always a different number, not only id string
Im trying to do this:
for ($i = 0; $i < count($array); $i++){
//$namesArray[] = array($array[$i]["id"] =>$array[$i]["name"].
// " ".$array[$i]["last"]." ".$array[$i]["name"]);
$namesArray[] = array_fill_keys(
$array[$i]["id"],
$array[$i]["name"]." ".
$array[$i]["last"]." ".
$array[$i]["name"]
);
}
echo json_encode($namesArray);
With the commented lines I get something like this:
[{"id":"name last name"},
{"id":"name last name"}
]
But I dont want that, I want all keys and values in a single array.
Thanks.
Keep your code clean
$array = [];
$array[] = ['id'=>3 , 'name'=>'H', 'last'=>'bensiali' ];
$array[] = ['id'=>4 , 'name'=>'Simon', 'last'=>'Says' ];
$array[] = ['id'=>5 , 'name'=>'Mohammed', 'last'=>'Ali' ];
$val = [];
foreach ($array as $key => $value) {
$val[$value['id']] = sprintf("%s %s" , $value['name'] , $value['last']);
}
echo json_encode($val);
And output will be:
{"3":"H bensiali","4":"Simon Says","5":"Mohammed Ali"}
Here is how you can do it:
// sample data
$array = array(
array("id" => 1, "name" => "James", "last" => "Last"),
array("id" => 2, "name" => "Micheal", "last" => "Jackson"),
);
// create empty object (associative array)
$obj = (object) array();
// add key/value pairs to that object
foreach ($array as $row) {
$obj->$row["id"] = $row["name"] . " " . $row["last"];
}
// wrap object in a single-element array
$result = array($obj);
// output to JSON string
echo json_encode($result, JSON_PRETTY_PRINT);
Output:
[
{
"1": "James Last",
"2": "Micheal Jackson"
}
]
You can use functional approach to fill desired array with array_reduce:
$array = [
['id' => 1, 'name' => 'name1', 'last' => 'last1'],
['id' => 2, 'name' => 'name2', 'last' => 'last2'],
['id' => 3, 'name' => 'name3', 'last' => 'last3'],
];
$newArray = array_reduce($array, function($carry, $item) {
$carry[$item['id']] = $item["name"]." ".
$item["last"]." ".
$item["name"];
return $carry;
});
var_dump($newArray);
And output will be:
array(3) {
[1]=>
string(17) "name1 last1 name1"
[2]=>
string(17) "name2 last2 name2"
[3]=>
string(17) "name3 last3 name3"
}
Let say I have an array as follows:
$my_array = array(
"fruit1" => "apple",
"fruit2" => "orange",
"notfruit" => "hamburger",
"fruit3" => "banana"
)
Is there a way I can choose to start with $my_array['notfruit'] in an foreach loop of PHP? I don't care the sequence except the first one.
Currently I can think of copying the whole piece of code once and change it specifically for $my_array['notfruit'], then unset it from the array to use foreach loop to go through the remaining. i.e.
echo $my_array['notfruit']."is not fruit. Who put that in the array?";
unset ($my_array['notfruit']);
foreach ($my_array as $values) {
echo $values." is fruit. I love fruit so I like ".$values;
}
It works but it sounds stupid, and can cause problem if the content in the foreach loop is long.
You can filter out any element with a key that doesn't begin with fruit pretty easily
$fruits = array_filter(
$my_array,
function ($key) {
return fnmatch('fruit*', $key);
},
ARRAY_FILTER_USE_KEY
);
var_dump($fruits);
though using array_filter() with the keys like this does require PHP >= 5.6
EDIT
For earlier versions of PHP, you can swap the keys/values before filtering; then flip them again afterwards
$fruits = array_flip(
array_filter(
array_flip($my_array),
function ($value) {
return fnmatch('fruit*', $value);
}
)
);
var_dump($fruits);
Short answer, no.
You can, however pull whatever functionality you intended to have in the foreach into a funcion, then call the funcion specifically for the notfruit value, then run the foreach.
function foo($val) {
// do stuff with $val
}
$my_array = array(
"fruit1" => "apple",
"fruit2" => "orange",
"notfruit" => "hamburger",
"fruit3" => "banana"
)
foo($my_array['nofriut']);
unset($my_array['nofruit']);
foreach($my_array as $val) {
foo($val);
}
EDIT
Or if your case is as simple as your updated question, simply check if the key is nofruit
foreach($my_array as $key => $val) {
if($key === "nofruit") {
echo "$val is not fruit. Who put that in the array?";
} else {
echo "$val is fruit. I love fruit so I like $val";
}
}
You can use addition in arrays, which is more performant than array_unshift.
So unset it, and then add it back:
unset($my_array['notfruit']);
$my_array = array('notfruit' => 'hamburger') + $my_array;
var_dump($my_array);
Or if you want to use a variable:
$keyToMove = 'notfruit';
$val = $my_array[$keyToMove];
unset($my_array[$keyToMove]);
$newArray = array($keyToMove => $val) + $my_array;
var_dump($newArray);
Obviously you can put this all in a loop, applying it to any that you need to move.
Try this..
<?php
$my_array = array(
"fruit1" => "apple",
"fruit2" => "orange",
"notfruit" => "hamburger",
"fruit3" => "banana"
);
$new_value['notfruit'] = $my_array['notfruit'];
unset($my_array['notfruit']);
$newarray=array_merge($new_value,$my_array);
print_r($newarray);
?>
Result:Array ( [notfruit] => hamburger [fruit1] => apple [fruit2] => orange [fruit3] => banana )
There is too many options.
1 . Using array_merge or array_replace (i think that it is the simplest way)
$my_array = array_merge(['notfruit' => null], $my_array);
// $my_array = array_replace(['notfruit' => null], $my_array);
foreach ($my_array as $key => $value) {
var_dump($key, $value);
}
2 . Using generators.
$my_array = array(
"fruit1" => "apple",
"fruit2" => "orange",
"notfruit" => "hamburger",
"fruit3" => "banana"
);
$generator = function($my_array){
yield 'notfruit'=>$my_array['notfruit'];
unset($my_array['notfruit']);
foreach($my_array as $key => $value)
yield $key => $value;
};
foreach ($generator($my_array) as $key=>$value){
var_dump($key, $value);
}
3 . Readding value
$no_fruit = $my_array['nofruit'];
unset($my_array['nofruit']);
$my_array['nofruit'] = $no_fruit;
$my_array = array_reverse($my_array, true);
foreach ($my_array as $key=>$value){
var_dump($key, $value);
}
4 . Using infinitive iterator
$infinate = new InfiniteIterator(new ArrayIterator($my_array));
$limit_iterator = new LimitIterator(
$infinate,
array_search('notfruit', array_keys($my_array)), // position of desired key
count($my_array));
foreach ($limit_iterator as $key => $value) {
var_dump($key, $value);
}
$no_fruit = $my_array['nofruit']; // grab the value
unset($my_array['nofruit']); // remove value from array
array_unshift($my_array, $no_fruit); // add value at the beginning
or
$no_fruit = $my_array['nofruit']; // grab the value
unset($my_array['nofruit']); // remove value from array
$my_array = array('nofruit' => $no_fruit ) + $my_array; // add value at the beginning