This would be easy to do with regular array with a simple for statement. EG:
$b= array('A','B','C');
$s=sizeof($b);
for ($i=0; $i <$s ; $i++) $b[$i]='your_face';
print_r($b);
But if I use assoc array, I can't seem any easy way to do it. I could, of course use a foreach loop, but it is actually replicating the $value variables instead of returning a pointer to an actual array entity. EG, this will not work:
$b= array('A'=>'A','B'=>'B','C'=>'C');
foreach ($b as $v) $v='your_face';
print_r($b);
Of course we could have some stupid idea like this:
$b= array('A'=>'A','B'=>'B','C'=>'C');
foreach ($b as $k => $v) $b[$k]='your_face';
print_r($b);
But this would be an awkward solution, because it would redundantly recreate $v variables which are never used.
So, what's a better way to loop through an assoc?
You could try:
foreach(array_keys($b) as $k) {
$b[$k] = 'your_face';
}
print_r($b);
See the following link for an explaination of array_keys: http://php.net/manual/en/function.array-keys.php
Not sure if that's what you want, but here goes:
foreach(array_keys($b) as $k) $b[$k] = 'your_face';
Related
More of a curiosity question. If you have an array of arrays, is there any shorthand for iterating over the interior arrays? You can obviously use the following to do it, but I wondered if there's a single line call that gets rid of the second foreach.
$arr = array(array(1,2,3), array(4,5,6), array(7,8,9));
foreach($arr as $interiorArr)
{
foreach($interiorArr as $number)
{
echo $number;
}
}
output would be "123456789"
Depending on what you're needing to do, you can recursively walk the array:
array_walk_recursive($arr, function($v) { echo $v; });
For this simple example (echo and print aren't functions so can't be used as a callback):
array_walk_recursive($arr, 'printf');
Again, depending on what you're needing to do, and for this simple example, you can foreach and use a variety of functions that operates on arrays:
foreach($arr as $interiorArr)
{
echo implode($interiorArr);
}
I have two large arrays:
$a = array('a1','a2','a3','a4'); // and so on
$b = array('b1'=>'a1', 'b2'=>'a3', 'b3'=>'a1'); //
I would like to get the following result:
$a = array('a1'=>array('b1', 'b3'), 'a2'=>array(), 'a3'=>array('b2') );
I could just do:
foreach($a as $aa){
foreach($b as $bb){
// check with if then add to a
}
}
but it would get tremendously large with bigger numbers.
So it occurred to me that if i remove each 'b' element after being added to $a the next loops will be smaller, and i would cut on resources.
However when splicing the looped array, the index does not seem to get updated, and the next loop does not take into consideration that fact that it was cut down by 1.
How can I make this work, and also, is there a better way of fitting items of an array into the appropriate indexes of another array?
EDIT:
how would this be done if the structure of both $a and $b were:
$a[0]['Word']['id']=1;
$a[0]['Word']['sentence_id']=2;
$a[0]['Word']['word_string']='someWord';
$b[0]['Word']['id']=3;
$b[0]['Word']['sentence_id']=4;
$b[0]['Word']['word_string']='someWord';
// And i would like to list `b` like so:
$a[0]['list_of_bs']=array(b[0], b[1]);
//So that i can get:
echo $a[0]['list_of_bs']['Word']['id'];
// and to get result 3
and i would like it to be $a[0][Word][list_of_b]=array(b1,b2,b3) and each of the b's has it's own data in associative array.
Try this,
$a = array('a1','a2','a3','a4');
$b = array('b1'=>'a1', 'b2'=>'a3', 'b3'=>'a1');
foreach($a as $values)
{
$key = array_keys($b, $values);
$new_array[$values] = $key;
}
$new_array -> will be the result that you need.
No there is no other way which removes load from the server.
You need to do this in this way only.
Even array_walk also need to perform it like in the loopy way.
The way you put together the two loops is not well thought. Don't put them together but after each other:
foreach ($a as $aa) {
// transform a
}
foreach ($b as $bb){
// check with if then add to a
}
This will make count(a) + count(b) iterations instead of count(a) * count(b) iterations - which is less unless a and b have only one element.
Taking idea from #hakre ..
Why not loop through $b
new_arr = new array
foreach $b as $bb
new_arry($bb->val).push($bb->key)
foreach $new_arry as $nn
if $nn doesn't exist in $a then remove
PHP's list keyword is nice for taking out variables from an array $a as below
$a = array(1,22);
list($b, $c) = $a;
var_dump("$a $b $c");
But for array $a2 in the form of key => value as below, I failed to use list
$a2 = array('b'=>1,'c'=>22);
list($b, $c) = $a2;
list($bkey, $b, $ckey, $c) = $a2;
list( list($bkey, $b), list($ckey,$c) ) = $a2;
var_dump("$a2 $b $c");
All of the three above assignments fail. I give up.
If you know how to get the key & value in array $a2, please help!
Following the comment of Mr Evil below (Col Shrapnel, see his profile), I never said following two ways are different, one could use either but I have advised using these methods on user-inputted data could create security problems, use it on your own risk or if there is no user-inputted data.
It does not seem to work with associatieve arrays, you can do something like this though:
foreach ($array as $key => $value) {
$$key = $value;
}
Example:
$a2 = array('b'=>1,'c'=>22);
foreach ($a2 as $key => $value) {
$$key = $value;
}
echo $b . '<br>';
echo $c;
Result:
1
22
One could also use extract() function but I generally avoid it because using it on user-inputted values could create security hazards. Depending on your choice, you might want to use it or if data isn't coming from users side.
I think you should use each function.
each() Return the current key and value pair from an array and advance the array cursor.
it seems it is extract() function you need
I am writing a foreach that does not start at the 0th index but instead starts at the first index of my array. Is there any way to offset the loop's starting point?
Keep it simple.
foreach ($arr as $k => $v) {
if ($k < 1) continue;
// your code here.
}
See the continue control structure in the manual.
A Foreach will reset the array:
Note: When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop.
Either use a for loop (only if this is not an associative array)
$letters = range('a','z');
for($offset=1; $offset < count($letters); $offset++) {
echo $letters[$offset];
}
or a while loop (can be any array)
$letters = range('a','z');
next($letters);
while($letter = each($letters)) {
echo $letter['value'];
}
or with a LimitIterator
$letters = new LimitIterator(new ArrayIterator(range('a','z')), 1);
foreach($letters as $letter) {
echo $letter;
}
which lets you specify start offset and count through the constructor.
All of the above will output the letters b to z instead of a to z
You can use the array_slice function:
$arr = array(); // your array
foreach(array_slice($arr, 1) as $foo){
// do what ever you want here
}
Of course, you can use whatever offset value you want. In this case, 1 'skip' the first element of the array.
In a foreach you cant do that. There are only two ways to get what you want:
Use a for loop and start at position 1
use a foreach and use a something like if($key>0) around your actual code
A foreach does what its name is telling you. Doing something for every element :)
EDIT: OK, a very evil solution came just to my mind. Try the following:
foreach(array_reverse(array_pop(array_reverse($array))) as $key => $value){
...
}
That would reverse the array, pop out the last element and reverse it again. Than you'll have a element excluding the first one.
But I would recommend to use one of the other solutions. The best would be the first one.
And a variation: You can use array_slice() for that:
foreach(array_slice($array, 1, null, true) as $key => $value){
...
}
But you should use all three parameters to keep the keys of the array for your foreach loop:
Seems like a for loop would be the better way to go here, but if you think you MUST use foreach you could shift the first element off the array and unshift it back on:
$a = array('foo','bar');
$temp = array_shift($a);
foreach ( $a as $k => $v ) {
//do something
}
array_unshift($a, $temp);
Well no body said it but if you don't mind altering the array and if we want to start from the second element of the given array:
unset($array[key($array)]);
foreach($array as $key=>$value)
{
//do whatever
}
if you do mind, just add,
$saved = $array;
unset($array[key($array)]);
foreach($array as $key=>$value)
{
//do whatever
}
$array = $saved;
Moreover if you want to skip a given known index, just subtitute
key($array)
by the given index
bismillah...
its simple just make own keys
$keys=1;
foreach ($namafile_doc as $value ) {
$data['doc'.$keys]=$value;
$keys++;
}
may this answer can make usefull
I have a function (for ease, I'll just use count()) that I want to apply to maybe 4-5 different variables. Right now, I am doing this:
$a = count($a);
$b = count($b);
$c = count($c);
$d = count($d);
Is there a better way? I know arrays can use the array_map function, but I want the values to remain as separate values, instead of values inside of an array.
Thanks.
I know you said you don't want the values to be in an array, but how about just creating an array specifically for looping through the values? i.e.:
$arr = Array($a, $b, $c, $d);
foreach ($arr as &$var)
{
$var = count($var);
}
I'm not sure if that really is much tidier than the original way, though.
If you have a bunch of repeating variables to collect data your code is poorly designed and should just be using an array to store the values, instead of dozens of variables. So perhaps you want something like:
$totals = array("Visa"=>0,"Mastercard"=>0,"Discover"=>0,"AmericanExpress"=>0);
then you simply add to your array element (say from a while loop from your SQL or whatever you are doing)
$totals['Visa'] += $row['total'];
But if you really want to go down this route, you could use the tools given to you, if you want to do this with a large batch then an array is a good choice. Then foreach the array and use variable variables, like so:
$variables = array('a','b','c'...);
foreach ( $variables as $var )
{
${$var} = count(${var});
}
What Ben and TravisO said, but use array_walk for a little cleaner code:
$arr = Array($a, $b, $c, $d);
array_walk($arr, count);
You can use extract to get the values back out again.
//test data
$a = range(1, rand(4,9));
$b = range(1, rand(4,9));
$c = range(1, rand(4,9));
//the code
$arr = array('a' => $a, 'b' => $b, 'c' => $c);
$arr = array_map('count', $arr);
extract($arr);
//whats the count now then?
echo "a is $a, b is $b and c is $c.\n";
How do you measure "better"? You might be able to come up with something clever and shorter, but what you have seems like it's easiest to understand, which is job 1. I'd leave it as it is, but assign to new variables (e.g. $sum_a, ...).