I'm a beginner in PHP.
My purpose is to print three sentences with a multi-dimensional array :
cats are smelly
birds are beautiful
snails are sticky
But the only sentence I'm able to print is "cats are smelly". I've tried many things. So here is the code:
<?php
$sentence = 'dogs are sweet';
$animals = array('#dogs#' => array('cats', 'birds', 'snails'),
'#sweet#' => array('smelly', 'beautiful', 'sticky'));
foreach ($animals as $key => $value)
{
foreach ($value as $subkey => $subvalue)
{
$sentence = preg_replace($key, $subvalue, $sentence);
}
}
echo $sentence . '</br>';
?>
How can I resolve this?
There are multiple layers as to why your solution doesn't work.
The sentence is only echoed once
Sentence is being replaced, so once "dogs" is replaced, it won't replace anything else because dogs isn't in the sentence anymore.
The script loops through the animals array only once.
Any item is replaced with any item (You specified you want cats to be smelly, birds to be beautiful and snails to be sticky, this means to compare index 0 of the first array with index 0 of the second array, index 1 with index 1, etc.).
I changed your script slightly to make sure it loops through the list thrice, for each time it echoes the output and the sentence is reset to it's default value so it can be changed again.
$animals = array('#dogs#' => array('cats', 'birds', 'snails'),
'#sweet#' => array('smelly', 'beautiful', 'sticky'));
for ($i = 0; $i < count(reset($animals)); $i++) {
$sentence = 'dogs are sweet';
foreach ($animals as $key => $value)
{
foreach ($value as $subkey => $subvalue)
{
if ($subkey === $i) {
$sentence = preg_replace($key, $subvalue, $sentence);
}
}
}
echo $sentence . "<br />";
}
The part count(reset($animals)) counts the value of the first element of the $animals array. So in this case array('cats', 'birds', 'snails'). The script assumes the first and the second array are always equal in size.
The if statement in the secondary foreach loop is to make sure the right element from one array is matched with the right element from the other.
I hope this helps
Related
This question already has answers here:
Array Foreach Loop Prints Last Item Only [closed]
(4 answers)
Closed 9 months ago.
I'm attempting to make a foreach loop to iterate over each item in an array, but it only captures the last item and does not iterate over the first one. I've stripped down the code to only show the relevant parts and added some commands to identify the problem as described above.
$message == "kk,ll";
$myArray = explode(',', $message);
print_r ($myArray);
foreach ($myArray as $value);
{
echo "$value <br>";
$array[] = $value;
}
print_r ($array);
The output is:
Array ( [0] => kk [1] => ll ) ll
Array ( [0] => ll )
You can see that when I use print_r() the array contains two items. But the foreach loop only loops over the last item. Adding the array elements into a new array inside the loop also ends up with an array containing only the last element. What am I doing wrong?
You have two mistakes in you code:
In your first line you have two equal signs which should only be one.
In your foreach loop, you have by mistake put an semicolon at the end:
foreach ($myArray as $value);
Doing this, the foreach loop will run, but the code inside the {} is actually placed outside the foreach loop, and thereby causing $value only to store the last element of the array.
The code should look like this:
$message = "kk,ll";
$myArray = explode(',', $message);
print_r ($myArray);
foreach ($myArray as $value) {
echo "$value <br>";
$array[] = $value;
}
print_r ($array);
your foreach just assigned the $value, but output nothing. This is caused by the ; after foreach, same as
foreach ($myArray as $value)
{}
And after this, the $value have the last element of $myArray, then
{
echo "$value <br>";
$array[] = $value;
}
only output the last element.
remove the ; after the Foreach like in the follow code
foreach ($myArray as $value)
{
echo "$value <br>";
$array[] = $value;
}
In Laravel Framework Use Code into Controller:
$dd = $categories->pluck( 'title' )->toArray();
foreach ( $dd as $key => $value ) {<br />
$array[$key] = '.' . $value;<br />
} <br />
$cat = implode( ',' , $array );
<br />
// Result Display : James,Mark,Helmet.....
Only remove the semicolon after foreach ($myArray as $value) or used it
How to access all the elements under each key of multidimensional array.
$multi = array
(
"Abhishek" => array("Choudhary", "Bunta", "Popy"),
"Bond" => array("One", "two", "three", "four"),
"Super" => array("T1", "T2")
);
$data = array("Abhishek","Bond","Super");
for($j = 0;$j<count($data);$j++)
{
echo "<br/>Main Array Value ".$data[$j]."<br/>";
for($i = 0;$i<count($data[$j]);$i++)
{
echo "sub Value ".$multi[$data[$j]][$i]." count ".count($data[$j]) ;
}
}
Now I want to iterate through each element of Abhishek , Bond and Super , so we can see Abhishek has 3 elements inside it but $data[$j] always return 1. If I increment then I can access Bunta
Currently the output is -
Main Array Value Abhishek
sub Value Bunta
Main Array Value Bond
sub Value two
Main Array Value Super
sub Value T2
and expected is:
**
Main Array Value Abhishek
sub Value choudhary
sub Value Bunta
sub Value Popy
:
:
Main Array Value Bond
sub Value two
Main Array Value Super
sub Value T2
**
Disclaimer : I am super new to PHP so may be my expectation can be invalid or I am missing some very silly thing.
i recommend you read some articles about multidim arrays, anyway your needs could be done with following code:
foreach($multi as $key => $value) {
echo "<br/>Main Array Value ".$key."<br/>";
for($i = 0; $i < sizeof($value); $i++) {
echo "sub Value ".$value[$i]." count ".sizeof($value) ;
}
}
PS: you don't need $data array
#bunta please check this out: PHP Foreach
You could use foreach instead.
Also:
PHP foreach loop through multidimensional array
HTH.
Using foreach() would be easier
foreach ($multi as $key => $subarray)
{
echo $key . '<br />';
foreach ($subarray as $subvalue)
{
echo ' - '.$subvalue . '<br />';
}
}
Will output
Abhishek
- Choudhary
- Bunta
- Popy
Bond
- One
- two
- three
- four
Super
- T1
- T2
Try this :
<?php
foreach($multi as $key => $value) {
echo "<br/>Parent Value ".$key."<br/>";
for($i = 0; $ < sizeof($value); $++) {
echo "Child Value ".$value[$i]." count ".sizeof($value) ;
}
}
?>
You are using wrong syntax to access it.
Thanks
All you need is use foreach to iterate on $multi array (if you just want to know the number of subelements for each element level 1):
<?php
echo "<br\>multiDimensional Array<br\>";
$multi = array("Abhishek" =>array
("Choudhary",
"Bunta",
"Popy"),
"Bond" => array
("One",
"two",
"three",
"four"),
"Super" => array
("T1",
"T2")
);
foreach( $multi as $value ){
echo " count ".count($value) ;
}
I have a problem with sorting of an array.
$infoGroup is the result of a 'ldap_get_entries' call earlier. As I step through this array I put the result in the array $names.
Then I want to sort $names in alfabetical order, I have tried a number of different methods but to no avail. The array always stays in the same order it was constructed.
What have I missed?
foreach($infoGroup[$i]['member'] as $member) {
//echo "<li>".$member;
$go = stripos($member, "n");
unset($names);
$ai++;
if ( $go == 1 ) {
// extract member name from string
$temp = substr($member, 0, stripos($member, ","));
// Strip the CN= and change to lowercase for easy handling
$temp = str_replace("cn=", "", $temp);
$names[$ai] = ($temp);
}
if (natsort($names)){
foreach ($names as $key => $val) {
echo "<li>";
echo "$key $val";
}
}
}
$ai = 0;
This is the result however I try to sort the $names array:
Henrik Lindbom
Klaus Rödel
Admin
Bernd Brandstetter
proxyuser
Patrik Löfström
Andreas Galic
Martin Stalder
Hmmm.. a bit hard to explain, but the issue is because you are sorting your array inside that foreach() loop. Essentially, since you are creating the array element in the iteration of the first loop, the natsort() only has 1 element to sort and your nested foreach() loop is only outputting that 1 element, which is then unset() at the second and further iterations...
Extract that second foreach() that sorts and outputs and remove the unset() from the top of the first loop. This should output your desired results.
Something like this...
foreach($infoGroup[$i]['member'] as $member) {
//echo "<li>".$member;
$go = stripos($member, "n");
$ai++;
if ( $go == 1 ) {
// extract member name from string
$temp = substr($member, 0, stripos($member, ","));
// Strip the CN= and change to lowercase for easy handling
$temp = str_replace("cn=", "", $temp);
$names[$ai] = ($temp);
}
}
if (natsort($names)){
foreach ($names as $key => $val) {
echo "<li>";
echo "$key $val";
}
}
$ai = 0;
I want to skip some records in a foreach loop.
For example, there are 68 records in the loop. How can I skip 20 records and start from record #21?
Five solutions come to mind:
Double addressing via array_keys
The problem with for loops is that the keys may be strings or not continues numbers therefore you must use "double addressing" (or "table lookup", call it whatever you want) and access the array via an array of it's keys.
// Initialize 25 items
$array = range( 1, 25, 1);
// You need to get array keys because it may be associative array
// Or it it will contain keys 0,1,2,5,6...
// If you have indexes staring from zero and continuous (eg. from db->fetch_all)
// you can just omit this
$keys = array_keys($array);
for( $i = 21; $i < 25; $i++){
echo $array[ $keys[ $i]] . "\n";
// echo $array[$i] . "\n"; // with continuous numeric keys
}
Skipping records with foreach
I don't believe that this is a good way to do this (except the case that you have LARGE arrays and slicing it or generating array of keys would use large amount of memory, which 68 is definitively not), but maybe it'll work: :)
$i = 0;
foreach( $array as $key => $item){
if( $i++ < 21){
continue;
}
echo $item . "\n";
}
Using array slice to get sub part or array
Just get piece of array and use it in normal foreach loop.
$sub = array_slice( $array, 21, null, true);
foreach( $sub as $key => $item){
echo $item . "\n";
}
Using next()
If you could set up internal array pointer to 21 (let's say in previous foreach loop with break inside, $array[21] doesn't work, I've checked :P) you could do this (won't work if data in array === false):
while( ($row = next( $array)) !== false){
echo $row;
}
btw: I like hakre's answer most.
Using ArrayIterator
Probably studying documentation is the best comment for this one.
// Initialize array iterator
$obj = new ArrayIterator( $array);
$obj->seek(21); // Set to right position
while( $obj->valid()){ // Whether we do have valid offset right now
echo $obj->current() . "\n";
$obj->next(); // Switch to next object
}
$i = 0;
foreach ($query)
{
if ($i++ < 20) continue;
/* php code to execute if record 21+ */
}
if want to skipped some index then make an array with skipped index and check by in_array function inside the foreach loop if match then it will be skip.
Example:
//you have an array like that
$data = array(
'1' => 'Hello world',
'2' => 'Hello world2',
'3' => 'Hello world3',
'4' => 'Hello world4',
'5' => 'Hello world5',// you want to skip this
'6' => 'Hello world6',// you want to skip this
'7' => 'Hello world7',
'8' => 'Hello world8',
'9' => 'Hello world8',
'10' => 'Hello world8',//you want to skip this
);
//Ok Now wi make an array which contain the index wich have to skipped
$skipped = array('5', '6', '10');
foreach($data as $key => $value){
if(in_array($key, $skipped)){
continue;
}
//do your stuf
}
You have not told what "records" actually is, so as I don't know, I assume there is a RecordIterator available (if not, it is likely that there is some other fitting iterator available):
$recordsIterator = new RecordIterator($records);
$limited = new LimitIterator($recordsIterator, 20);
foreach($limited as $record)
{
...
}
The answer here is to use foreach with a LimitIterator.
See as well: How to start a foreach loop at a specific index in PHP
I'm not sure why you would be using a foreach for this goal, and without your code it's hard to say whether this is the best approach. But, assuming there is a good reason to use it, here's the smallest version I can think of off the top of my head:
$count = 0;
foreach( $someArray as $index => $value ){
if( $count++ < 20 ){
continue;
}
// rest of foreach loop goes here
}
The continue causes the foreach to skip back to the beginning and move on to the next element in the array. It's extremely useful for disregarding parts of an array which you don't want to be processed in a foreach loop.
for($i = 20; $i <= 68; $i++){
//do stuff
}
This is better than a foreach loop because it only loops over the elements you want.
Ask if you have any questions
array.forEach(function(element,index){
if(index >= 21){
//Do Something
}
});
Element would be the current value of index.
Index increases with each turn through the loop.
IE 0,1,2,3,4,5;
array[index];
I'm wondering if the elements of array can 'know' where they are inside of an array and reference that:
Something like...
$foo = array(
'This is position ' . $this->position,
'This is position ' . $this->position,
'This is position ' . $this->position,
),
foreach($foo as $item) {
echo $item . '\n';
}
//Results:
// This is position 0
// This is position 1
// This is position 2
They can't "reference themselves" per se, and certainly not via a $this->position as array elements are not necessarily objects. However, you should be tracking their position as a side-effect of iterating through the array:
// Sequential numeric keys:
for ($i = 0; $i < count($array); ++$i) { ... }
// Non-numeric or non-sequential keys:
foreach (array_keys($array) as $key) { ... }
foreach ($array as $key => $value) { ... }
// Slow and memory-intensive way (don't do this)
foreach ($array as $item) {
$position = array_search($item, $array);
}
No, PHP's arrays are plain data structures (not objects), without this kind of functionality.
You could track where in the array you are by using each() and keeping track of the keys, but the structure itself can't do it.
As you can see here: http://php.net/manual/en/control-structures.foreach.php
You can do:
foreach($foo as $key => $value) {
echo $key . '\n';
}
So you can acces the key via $key in that example