php: foreach() how to assign to two variables - php

function example()
{
foreach ($choices as $key => $choice) { # \__ both should run parallel
foreach ($vtitles as $keystwo => $vtitle) { # /
$options .= '<option value="'. check_plain($key) .'" title="' . $vtitle . '"' . $selected
.'>'. check_plain($choice) .'</option>';
} // end of vtitle
} // end of choice
return $options;
}
Answers to some of the below questions and what I am trying to achieve.
Array $choices is not numerically indexed.
Array $vtitle is numerically indexed.
They won't be shorter than each other as I have code which will take care of this before this code runs.
I am trying to return $options variable. The issue is that $choices[0] and $vtitle[0] should be used only once. Hope I was able to express my problem.
I do not want to go through the $vtitles array once for each value in $choices.
#hakre: thanks I have nearly solved it with your help.
I am getting an error for variable $vtitle:
InvalidArgumentException: Passed variable is not an array or object, using empty array
instead in ArrayIterator->__construct() (line 35 of /home/vishal/Dropbox/sites/chatter/sites
/all/themes/kt_vusers/template.php).
I am sure its an array this is the output using print_r
Array ( [0] => vishalkh [1] => newandold )
What might be going wrong ?
The below worked for me , thank you hakre
while
(
(list($key1, $value1) = each($array1))
&& (list($key2, $value2) = each($array2))
)
{
printf("%s => %s, %s => %s \n", $key1, $value1, $key2, $value2);
}

It does not work the way you outline with your pseudo code. However, the SPL offers a way to iterate multiple iterators at once. It's called MultipleIterator and you can attach as many iterators as you like:
$multi = new MultipleIterator();
$multi->attachIterator(new ArrayIterator($array1));
$multi->attachIterator(new ArrayIterator($array2));
foreach($multi as $value)
{
list($key1, $key2) = $multi->key();
list($value1, $value2) = $value;
}
See it in action: Demo
Edit: The first example shows a suggestion from the SPL. It has the benefit that it can deal with any kind of iterators, not only arrays. If you want to express something similar with arrays, you can achieve something similar with the classic while(list()=each()) loop, which allows more expressions than foreach.
while
(
(list($key1, $value1) = each($array1))
&& (list($key2, $value2) = each($array2))
)
{
printf("%s => %s, %s => %s \n", $key1, $value1, $key2, $value2);
}
Demo (the minimum number of elements are iterated)
See as well a related question: Multiple index variables in PHP foreach loop

you can't do it in foreach loop in general case. But you can do it like this in PHP5:
$obj1 = new ArrayObject($arr1);
$it1 = $obj1->getIterator();
$obj2 = new ArrayObject($arr2);
$it2 = $obj2->getIterator();
while( $it1->valid() && $it2->valid())
{
echo $it1->key() . "=" . $it1->current() . "\n";
$it1->next();
echo $it2->key() . "=" . $it2->current() . "\n";
$it2->next();
}
In older versions of PHP it will be like this:
while (($choice = current($choices)) && ($vtitle = current($vtitles))) {
$key_choice = key($choices);
$key_vtitle = key($vtitles);
next($choices);
next($vtitles);
}

Short Answer, no.
What you can do instead is:
foreach ($array1 as $k => $v)
performMyLogic($k, $v);
foreach ($array2 as $k => $v)
performMyLogic($k, $v);

If the keys are the same, you can do this:
foreach ($choices as $key => $choice) {
$vtitle = $vtitles[$key];
}

You may have to refigure your logic to do what you want. Any reason you can't just use 2 foreach loops? Or nest one inside the other?
EDIT: as others have pointed out, if PHP did support what you're trying to do, it wouldn't be safe at all.. so it's probably a good thing that it doesn't :)

Maybe you want this:
//get theirs keys
$keys_choices = array_keys($choices);
$keys_vtitles = array_keys($vtitles);
//the same size I guess
if (count($keys_choices) === count($keys_vtitles)) {
for ($i = 0;$i < count($keys_choices); $i++) {
//First array
$key_1 = $keys_choices[$i];
$value_1 = $choices[$keys_choices[$i]];
//second_array
$key_2 = $key_vtitles[$i];
$value_2 = $vtitles[$keys_vtitles[$i]];
//and you can operate
}
}
But this will work if size is the same. But you can change this code.

You need to use two foreach loops.
foreach ($choices as $keyChoice => $choice)
{
foreach ($vtitles as $keyVtitle => $vtitle)
{
//Code to work on values here
}
}

Related

What's Faster/More Efficient For Grabbing First 10 Elements In Array

I need the key, value, and index of the first 10 elements of my sorted associative array.
$top10pts = array_slice($toppoints, 0, 10);
foreach ($top10pts as $key => $val) {
echo "<tr><td>".(array_search($key, array_keys($top10pts))+1)."</td><td>".htmlentities($key)."</td><td>".$val."</td></tr>";
}
or
for ($i=0; $i<10; $i++) {
$val = array_slice($toppoints, $i, 1);
echo "<tr><td>".($i+1)."</td><td>".htmlentities(key($val))."</td><td>".$val[key($val)]."</td></tr>";
}
or another method?
Being new to PHP, both methods seem stupid and superfluous.
This is the best method that came to my mind.
$top10pts = array_slice($toppoints, 0, 10);
$i = 1;
foreach ($top10pts as $key => $val)
echo "<tr><td>".($i++)."</td><td>".htmlentities($key)."</td><td>".$val."</td></tr>";
Notice that, for more than 10 items, this method works better because it has no conditions in the loop. In interpreters such as php, it's usually better to use internal functions rather than doing the things yourself.
Similar to ernie's answer but you dont need array slice at all
$index = 0;
foreach ($top10pts as $key => $val) {
echo "<tr><td>".$index++."</td><td>".htmlentities($key)."</td><td>".$val."</td></tr>";
if($index >=10) break;
}
Since you sorted already, a foreach will iterate in order, so I'd use a modification of your first, getting rid of the array_search: . . .
$index = 0;
$top10pts = array_slice($toppoints, 0, 10);
foreach ($top10pts as $key => $val) {
echo "<tr><td>".$index."</td><td>".htmlentities($key)."</td><td>".$val."</td></tr>";
$index++;
}

PHP Nested loops where values are the key to the next level of the array

I'm relatively new to PHP and I hope you can help me solve my problem. I am selecting out data from a database into an array for timekeeping. Ultimately, I would like to calculate the total number of hours spent on a project for a given customer.
Here is the code to populate a multi-dimensional array:
...
foreach ($record as $data) {
$mArray = array();
$name = $data['user'];
$customer = $data['customer'];
$project = $data['project'];
$hours = $data['hours'];
$mArray[$name][$customer][$project] += $hours;
}
...
I would now like to iterate over $mArray to generate an xml file like this:
...
foreach ($mArray as $username) {
foreach ($mArray[$username] as $customerName) {
foreach ($mArray[$username][$customerName] as $project ) {
echo '<'.$username.'><'.$customerName.'><'.$project.'><hours>'.
$mArray[$username][$customerName][$project].'</hours></'.$project.'>
</'.$customerName.'></'.$username.'>';
}
}
}
This nested foreach doesn't work. Can someone give me a couple of tips on how to traverse this structure? Thank you for reading!
UPDATE:
Based on the comments I've received so far (and THANK YOU TO ALL), I have:
foreach ($mArray as $userKey => $username) {
foreach ($mArray[$userKey] as $customerKey => $customerName) {
foreach ($mArray[$userKey][$customerKey] as $projectKey => $projectName) {
echo '<name>'.$userKey.'</name>';
echo "\n";
echo '<customerName>'.$customerKey.'</customerName>';
echo "\n";
echo '<projectName>'.$projectKey.'</projectName>';
echo "\n";
echo '<hours>'.$mArray[$userKey][$customerKey][$projectKey].'</hours>';
echo "\n";
}
}
}
This is now only providing a single iteration (one row of data).
Foreach syntax is foreach($array as $value). You're trying to use those values as array keys, but they're not values - they're the child arrays. What you want is either:
foreach($mArray as $username) {
foreach($username as ...)
or
foreach($mArray as $key => $user) {
foreach($mArray[$key] as ...)

How to echo out the values of this array?

How to echo out the values individually of this array?
Array ( [0] => 20120514 [1] => My Event 3 )
so
echo $value[0]; etc
I have this so far:
foreach (json_decode($json_data_string, true) as $item) {
$eventDate = trim($item['date']);
// positive limit
$myarray = (explode(',', $eventDate, 2));
foreach ($myarray as $value) {
echo $value;
}
This echo's out the whole string no as an array. and if i do this?
echo $value[0};
Then I only get 2 characters of it??
The print_r :
Array ( [0] => 20120430 [1] => My Event 1 )
foreach ($array as $key => $val) {
echo $val;
}
Here is a simple routine for an array of primitive elements:
for ($i = 0; $i < count($mySimpleArray); $i++)
{
echo $mySimpleArray[$i] . "\n";
}
you need the set key and value in foreach loop for that:
foreach($item AS $key -> $value) {
echo $value;
}
this should do the trick :)
The problem here is in your explode statement
//$item['date'] presumably = 20120514. Do a print of this
$eventDate = trim($item['date']);
//This explodes on , but there is no , in $eventDate
//You also have a limit of 2 set in the below explode statement
$myarray = (explode(',', $eventDate, 2));
//$myarray is currently = to '20'
foreach ($myarray as $value) {
//Now you are iterating through a string
echo $value;
}
Try changing your initial $item['date'] to be 2012,04,30 if that's what you're trying to do. Otherwise I'm not entirely sure what you're trying to print.
var_dump($value)
it solved my problem, hope yours too.

php array keys problem

I have the following code:
$rt1 = array
(
'some_value1' => 'xyz1',
'some_value2' => 'xyz2',
'value_1#30'=>array('0'=>1),
'value_2#30'=>array('0'=>2),
'value_3#30'=>array('0'=>3),
'value_1#31'=>array('0'=>4),
'value_2#31'=>array('0'=>5),
'value_3#31'=>array('0'=>6),
'some_value3' => 'xyz3',
'some_value4' => 'xyz4',
);
$array_30 = array
(
'0'=>1,
1=>'2',
2=>'3'
);
$array_31 = array
(
'0'=>4,
'1'=>'5',
'2'=>'6'
);
I need to make it an array and insert the array_30 and array_31 into a DB.
foreach($rt1 as $value){
$rt2[] = $value['0'];
}
The question was updated, so here is an updated answer. Quick check, you should really try and update this to whatever more generic purpose you have, but as a proof of concept, a runnable example:
<?php
$rt1 = array
(
'some_value1' => 'xyz1',
'some_value2' => 'xyz2',
'value_1#30'=>array('0'=>1),
'value_2#30'=>array('0'=>2),
'value_3#30'=>array('0'=>3),
'value_1#31'=>array('0'=>4),
'value_2#31'=>array('0'=>5),
'value_3#31'=>array('0'=>6),
'some_value3' => 'xyz3',
'some_value4' => 'xyz4',
);
$finalArrays = array();
foreach($rt1 as $key=>$value){
if(is_array($value)){
$array_name = "array_".substr($key,-2);
${$array_name}[] = $value['0'];
}
}
var_dump($array_30);
var_dump($array_31);
?>
will output the two arrays with the numbers 1,2,3 and 4,5,6 respectivily
i assume you want to join the values of each of the second-level arrays, in which case:
$result = array();
foreach ($rt1 as $arr) {
foreach ($arr as $item) {
$result[] = $item;
}
}
Inspired by Nanne (which reminded me of dynamically naming variables), this solution will work with every identifier after the \#, regardless of its length:
foreach ( $rt1 as $key => $value )
{
if ( false == strpos($key, '#') ) // skip keys without #
{
continue;
}
// the part after the # is our identity
list(,$identity) = explode('#', $key);
${'array_'.$identity}[] = $rt1[$key]['0'];
}
Presuming that this is your actual code, probably you will need to copy the array somewhere using foreach and afterwards create the new array as you wish:
foreach($arr as $key => $value) {
$arr[$key] = 1;
}

PHP sort an array of hyperlinks by link text

I have an array of hyperlinks being generated from ab object for display on a page. The link text is all that is displayed on the page. I need to sort the hyperlinks/link text alphabetically.
Here is what I have:
foreach ($value as $key1 => $value1) {
if ($key1 == 'id') {
$id = $value1;
}
if ($key1 == 'name') {
$link = '' . $value1 . '<br>';
array_push($stack, $link);
}
}
asort($stack);
print_r($stack);
The asort call on $stack does not sort the array by link text.
I think this may call for a regexp on the subset of the hyperlink string in the array, and then a string compare and switch in the array, but am at a loss on how to do that in PHP.
Any ideas much appreciated.
According to the code given, the link text is what's in $value1. So you can sort based on that.
Assuming that the link text can be used as an array key (doesn't contain invalid key characters) you can add them to an array as such: $links[$value1] = '' . $value1 . '<br>'; and then sort them by key ksort($links);
I suspect that id is unique. So first create a nice key/value array then sort it. Then fill stack with sorted hyperlinks
$links = array();
foreach ($value as $key1 => $value1)
{
if ($key1 == 'id') {
$id = $value1;
}
if ($key1 == 'name') {
$links[$id] = $value1;
}
}
asort($links);
print_r($links);
foreach($links as $id=>$name)
{
$link = '' . $name. '<br>';
array_push($stack, $link);
}
Off the top of my head, something like this should work:
$keys = asort(array_keys($stack));
$sorted = array();
foreach ($keys as $key) {
$sorted[$key] = $stack[$key];
}
sorting the array could be done like so:
array_sort($value, 'linkname', SORT_ASC)
and then parse it within the foreach loop. More information about sorting an array from a query by a specific key could be found in the php manual: sort

Categories