My code is below.
1) I needed to get the number of words in each message in the message array and display it in a new array
2) If the number of words in each message was less than 5 I am supposed to add the words "smaller" to another new array and if the number of words in each message is greater than 5 I an supposed to add the string"bigger" to this same new array.
I am unsure of how to put this "bigger" and "smaller" into a new array. Please advise.(refer question 2)
$messages = array(
"Learning PHP is fun",
"I want to learn more",
"Girls can code too",
"Goodbye boredom!",
"Coding Geek",
"Computers can sometimes freeze up",
"Follow me now", "Coding is cool",
"Computer nerds are for real",
"This is the end of all the messages"
);
/* (1) */
for ($i = 0; $i < 10; $i++) {
$words[] = str_word_count($messages[$i]);
}
print_r($words);
echo "<br>";
/* (2) */
for ($i = 0; $i < 10; $i++) {
if ($words[$i] <= 5) {
$size[] = $words[$i];
echo "smaller" . "<br>";
} else {
$size[] = $words[$i];
echo"bigger";
}
}
First, you can use foreach instead of for loop in this case.
Second, this code is enough.Try it :
foreach($messages as $val){
$len = str_word_count($val);
if($len<=5){
$msg = "bigger";
}else{
$msg = "smaller";
}
$size[] = array("size"=>$len, "msg"=>$msg);
}
# Your $size array would be like :
# array(
# array("size"=>3, "msg"=>"smaller"),
# array("size"=>8, "msg"=>"bigger")
# )
# And you can print it or use it everywhere.
for loops work fine for arrays. You could think about using a variable which holds the length of the original array to use in the loop.
$numberOfMessages = count($messages);
$for ($i = 0; $i < $numberOfMessages; $i ++) {
...
}
My preferred way of doing this is the same as the first two examples using a foreach loop.
foreach ($messages as $message) {
$words[] = str_word_count($message);
}
This will create your first new array called $words by counting the number of words in each value ($message) from the original array ($messages). Using the <pre> tag formats the echo and makes it more readable.
echo '<pre>' . print_r($words, true) . '</pre>';
Your second new array is made is a similar way.
foreach ($words as $word) {
if ($word < 5) {
$size[] = 'smaller';
} else {
$size[] = 'bigger';
}
}
This time we take each value ($word) from our new $words array and check to see what size it is and populate the second new array $size. bablu's example using the ternary operator ?: This example is just the long-hand way of writing the same conditional statement.
Putting it all together
$messages = array (
'Learning PHP is fun',
'I want to learn more',
'Girls can code too',
'Goodbye boredom!',
'Coding Geek',
'Computers can sometimes freeze up',
'Follow me now', 'Coding is cool',
'Computer nerds are for real',
'This is the end of all the messages'
);
foreach ($messages as $message) {
$words[] = str_word_count($message);
}
echo '<pre>' . print_r($words, true) . '</pre>';
foreach ($words as $word) {
if ($word < 5) {
$size[] = 'smaller';
} else {
$size[] = 'bigger';
}
}
echo '<pre>' . print_r($size, true) . '</pre>';
Try this: its working fine for me:
<?php
$messages=array
("Learning PHP is fun","I want to learn more","Girls can code too","Goodbye boredom!","Coding Geek","Computers can sometimes freeze up","Follow me now","Coding is cool","Computer nerds are for real","This is the end of all the messages");
$newMessageArray = array();
$newCountArray = array();
foreach($messages as $message) {
$length = str_word_count($message);
$newMessageArray[] = $message;
$newCountArray[] = ($length >=5)?'Bigger':'Smaller';
}
echo '<pre>'; print_r($newMessageArray);
echo '<pre>'; print_r($newCountArray);
?>
Related
Here is my code, and it is not removing $arr[5] element so that I am trying to remove strings starting with # from my array
this is code
<?php
$arr = [
'#EXTM3U',
'#EXTINF:177,Paul Dateh & Oren Yoel - Be More',
'Be More.mp3',
'#EXTINF:291,Christopher Toy - Just Because',
'Just Because.mp3',
'#EXTINF:238,Magnetic North - Drift Away',
'Drift Away.mp3'
];
for ($i = 0; $i <= count($arr); $i++) {
if ($arr[$i]{0} == '#') {
echo $arr[$i] . "\n";
unset($arr[$i]);
}
}
print_r($arr);
?>
Reason:- You are counting array length inside the loop and every time when any value got unset() from the array, length of array decreased and value of count($array) changed (simply decreased)
So logically your 5th and 6th element never goes through if condition (they never get traversed by loop because of decreasing length of the array )
Solution 1:- Put count outside and it will work properly:-
$count = count($arr);
//loop start from 0 so use < only otherwise, sometime you will get an undefined index error
for ($i = 0; $i < $count; $i++) {
if ($arr[$i]{0} == '#') {
//echo $arr[$i] . "\n";
unset($arr[$i]);
}
}
print_r($arr);
Output:-https://eval.in/996494
Solution 2:- That's why i prefer foreach() over for() loop
foreach($arr as $key=> $ar){
if ($ar[0] == '#') {
unset($arr[$key]);
}
}
print_r($arr);
Output:-https://eval.in/996502
more spacific :
for ($i = 0; $i < count($arr); $i++) {
if (strpos($arr[$i], '#') !== false) {
echo "<br/>";
} else {
echo $arr[$i]."<br/>";
}
}
Try to use additional array to push right values. You calc count($arr); each iteration and when you do count($arr); your array gets smaller and count($arr); returns smaller values, so last elements won't be comparing, try to use variable to calc count before loop make changes:
<?php
//...
$start_count = count($arr);
for ($i = 0; $i <= $start_count; $i++) {
if ($arr[$i]{0} == '#') {
echo $arr[$i] . "\n";
unset($arr[$i]);
}
}
Or remove bad element with a help of additional array, put good elements in new array and don't delete them from input array:
<?php
$arr = [
'#EXTM3U',
'#EXTINF:177,Paul Dateh & Oren Yoel - Be More',
'Be More.mp3',
'#EXTINF:291,Christopher Toy - Just Because',
'Just Because.mp3',
'#EXTINF:238,Magnetic North - Drift Away',
'Drift Away.mp3'
];
$cleared_from_mess_array = array();
for ($i = 0; $i <= count($arr); $i++) {
if ($arr[$i]{0} != '#')
{
array_push($cleared_from_mess_array,$arr[$i]);
}
}
print_r($cleared_from_mess_array);
exit;
I would like to Convert simple string to another format based on below logic
Example 1 : if string is 3,4-8-7,5 then I need the set as (3,8,7),(4,8,5).
Example 2: If string is "4-5,6-4" then required set will be (4,5,4),(4,6,4).
More Clear Requirements:
if string is 5-6,7,8-2,3-1. It need to be divided first like [5] AND [(6) OR (7) OR (8)] AND [(2) OR (3)] AND [1]. Result must be All possible combination: (5,6,2,1),(5,6,3,1),(5,7,2,1),(5,7,3,1),(5,8,2,1),(5,8,3,1).
The Logic behind to building the set are we need to consider ',' as OR condition and '-' as AND condition.
I am trying my best using For loop but unable to find solution
$intermediate = array();
$arry_A = explode('-', '3,4-8-7,5');
for ($i = 0; $i < count($arry_A); $i++) {
$arry_B = explode(',', $arry_A[$i]);
for ($j = 0; $j < count($arry_B); $j++) {
if (count($intermediate) > 0) {
for ($k = 0; $k < count($intermediate); $k++) {
$intermediate[$k] = $intermediate[$k] . ',' . $arry_B[$j];
}
} elseif (count($intermediate) === 0) {
$intermediate[0] = $arry_B[$j];
}
}
}
echo $intermediate, should give final result.
Cool little exercise!
I would do it with the following code, which I will split up for readability:
I used an array as output, since it's easier to check than a string.
First, we initialize the $string and create the output array $solutions. We will calculate the maximum of possible combinations from the beginning ($results) and fill the $solutions array with empty arrays which will be filled later with the actual combinations.
$string = '3,4-8-7,5';
$solutions = array();
$results = substr_count($string,',')*2;
for($i = 0; $i < $results; $i++) {
array_push($solutions,array());
}
We will need two helper functions: checkSolutions which makes sure, that the combination does not yet exist more than $limit times. And numberOfORAfterwards which will calculate the position of an OR pattern in the $string so we can calculate how often a combination is allowed in the single steps of the walkthrough.
function checkSolutions($array,$solutions,$limit) {
$count = 0;
foreach($solutions as $solution) {
if($solution === $array) $count++;
}
if($count < $limit) return true;
else return false;
}
function numberOfORAfterwards($part,$parts) {
foreach($parts as $currPart) {
if($currPart === $part) $count = 0;
if(isset($count)) if(!ctype_digit($currPart)) $count++;
}
return $count;
}
Now the main part: We are going to loop over the "parts" of the $string a part are the digits between AND operations.
If you need further explanation on this loop, just leave a comment.
$length = 0;
// split by all AND operations
$parts = explode('-',$string);
foreach($parts as $part) {
if(ctype_digit($part)) {
// case AND x AND
foreach($solutions as &$solution) {
array_push($solution,$part);
}
} else {
// case x OR x ...
$digits = explode(',',$part);
foreach($digits as $digit) {
for($i = 0; $i < $results/count($digits); $i++) {
foreach($solutions as &$solution) {
if(count($solution) == $length) {
$test = $solution;
array_push($test,$digit);
$limit = numberOfORAfterwards($part,$parts);
echo $digit.' '.$limit.'<br>';
if(checkSolutions($test,$solutions,$limit)) {
array_push($solution,$digit);
break;
}
}
}
}
}
}
$length++;
}
print_r($solutions);
Some tests:
String: 3,4-8-7,5
Combinations: (3,8,7)(3,8,5)(4,8,7)(4,8,7)
String: 5-6,7,8-2,3-1
Combinations: (5,6,2,1)(5,6,3,1)(5,7,2,1)(5,7,3,1)(5,8,2,1)(5,8,2,1)
String: 2,1-4-3,2-7,8-9
Combinations: (2,4,3,7,9)(2,4,3,8,9)(2,4,2,7,9)(1,4,3,7,9)(1,4,2,8,9)(1,4,2,8,9)
String: 1,5-3,2-1
Combinations: (1,3,1)(1,2,1)(5,3,1)(5,3,1)
I have been thinking for hours but i still cant get a solution for this
Basically what i want to do is to echo a separator inside a while, it should be something like this
$num = 1;
while($num < 3){
echo 'dog';
//function to stop while
echo 'separator';
//function to continue while
echo 'cat';
$num++;
}
I want to get this output
dog
dog
dog
separator
cat
cat
cat
I dont know if i explained myself well but hope you understand. Thank you very much in advance.
Update: I know i can make this with 2 while functions but is it possible to make it using only one while function?
definitely yes you can with one while ~function. :)
function OnlyOneWhileFunction($echoThis, $howManyTimes){
$i = 1;
while($i <= $howManyTimes){
echo $echoThis."\r\n";
$i++;
}
}
OnlyOneWhileFunction('dog', 3);
echo 'separator';
OnlyOneWhileFunction('cat', 3);
$num = 0;
$dogs = '';
$cats = '';
$seperator = 'seperator';
while($num < 3){
$dogs .= 'dog';
$cats .= 'cat';
$num++;
}
echo $dogs . $seperator . $cats;
Save the output of each of the dogs and cats then combine at end.
Alternate solution:
$items = array_reverse(array("cat","dog"));
$output = array();
while(count($items) > 0)
{
$item = array_pop($items);
$output[] = implode("\n", array_fill(0, 3, $item));
}
echo implode("\nseparator\n", $output);
You can replace \n with <br> for HTML output (or use nl2br).
Try this:
<?php
$num = 0;
while($num < 7){
if($num < 3)
echo 'dog';
elseif($num == 3)
echo 'separator';
elseif($num>3)
echo 'cat';
echo "<br>";
$num++;
}
?>
You would be better off using a C style for loop and a function call for this:
$recho = function($out, $limit) {
for ($x=0; $x<$limit; $x++) {
echo $out . "\n";
}
}
$recho('dog',3);
echo "seperator\n";
$recho('cat',3);
Put this inside a <pre> on a webpage to get your line breaks, or replace the "\n" with <br> tags.
The following code should work:
$num = 0;
while($num <= 6){
if($num < 3) echo 'dog<br/>';
else if($num == 3) echo 'separator<br/>';
else echo 'cat<br/>';
$num++;
}
Here's another approach if you wanted n number of options and assuming each option is iterated over the same number of times. I'd do some cleanup but this is a quick and dirty approach:
<?php
/**
* Loops items with separator every nth time
* #param array list of items
* #param integer number of iterations
* #param string separator text
*/
function loopItemsWithSeparator(array $items, $count, $separator) {
$items = array_reverse($items);
while(!empty($items)) {
$item = array_pop($items);
for($i = 0; $i < $count; $i++) {
echo $item . "\n";
}
if (count($items) > 0) {
echo($separator . "\n");
}
}
}
loopItemsWithSeparator(array('dog', 'cat', 'bird'), 3, 'separator');
?>
I compare a string from a feed with another variable and echo a corresponding string.
$xml = #simplexml_load_file($feed);
foreach ($xml->entry as $entry) {
$caller = $entry->caller[0];
$message = $entry->message[0];
}
if (($caller == $id) {
echo '$message';
}
I want to echo no more than 5 messages, regardless of the number of ($caller == $id) matches.
$x=1;
while (($caller == $id) && ($x<=5)) {
echo '$x $message';
$x++;
}
That general approach has failed.
I thought maybe I could put the condition in a function and call it a certain number of times but no luck.
function myFunction(){
echo '$message';
}
$x=1;
while($x<=5) {
echo '$x';
myFunction();
$x++;
}
For one, your while loop would actually only output 4 results because you are saying while x is LESS than 5, not <= 5. You can leave it < 5, but change x to equal 0 instead of 1;
The second problem is that as soon as $caller does not == $id, your while loop will stop. You should only need to use a foreach loop for this, not both a foreach to extract the data and a while to loop over it again.
The third problem with your code is that you are writing your caller and message values to the same variable over and over in your foreach. Then, in your while loop, your $caller and $message variables will always be equal to the last items in the $xml->entry array.
$xml = #simplexml_load_file($feed);
$number_of_results_to_show = 5;
$x = 0; // counter
foreach ($xml->entry as $entry) {
$caller = $entry->caller[0];
$message = $entry->message[0];
if ($caller == $id && $x < $number_of_results_to_show) {
$x++;
echo $message;
}
// also, you can use a break to prevent your loop from continuing
// even though you've already output 5 results
if ($x == $number_of_results_to_show) {
break;
}
}
I assume that you have an array $xml->entry and you want to print message[0] of up to 5 array elements. Message is printed if $caller matches $id.
$xml = #simplexml_load_file($feed);
// Iterate through $xml->entry until the end or until 5 printed messages
for($i = 0, $j = 0; ($i < count($xml->entry)) && ($j < 5); ++$i) {
$caller = $xml->entry[$i]->caller[0];
$message = $xml->entry[$i]->message[0];
if ($caller == $id) {
echo "$message";
++$j;
}
}
If you want to store results from $xml->entry then:
$xml = #simplexml_load_file($feed);
$storedResults = new array();
foreach($xml->entry as $entry) {
$caller = entry->caller[0];
$message = entry->message[0];
// Store data in array. $storedResults will be an array of arrays
array_push(storedResults, array( 'caller' => $caller, 'message' => $message ));
}
// Print up to 5 messages from the stored results
$i = 0, $j = 0;
while (($i < count($storedResults)) && ($j < 5)) {
if ($storedResults[$i]['caller'] == $id) {
echo $storedResults[$i]['message'];
++$j;
}
++$i;
}
I am having the following problem. I have the numbers 1/2/3/4/5/6 and I want to separate them into two groups 1/3/5 and 2/4/6. The selection must take place based on the position. This part works ok. The problem comes when I want to group them again, when I use the implode function; it only sees the last number that was stored. I know it has something to do with me using this notation (I chose this way since the amount of numbers to classify varies every time):
$q++;
$row0 = $row0 + 2;
$row1 = $row1 + 2;
but I can't figure a way to fix it or another way to get the same result. Hopefully someone here can point me in the right direction. I left the complete code below.
<?
$string = "1/2/3/4/5/6";
$splitted = explode("/",$string);
$cnt = count($splitted);
$q=0;
$row0=0;
$row1=1;
while($cnt > 2*$q)
{
$p_row = implode(array($splitted[$row0]));
echo "$p_row <br>";
$i_row = implode(array($splitted[$row1]));
echo "$i_row <br>";
$q++;
$row0 = $row0 + 2;
$row1 = $row1 + 2;
}
$out = "implode(',', $i_row)";
var_dump($out);
?>
I missread the problem it seems. Instead I give this optimization.
$string = "1/2/3/4/5/6";
$splitted = explode("/", $string);
$group = array();
for ($index = 0, $t = count($splitted); $index < $t; ++$index) {
$group[$index & 1][] = $splitted[$index];
}
$oddIndex = $group[0]; //start with index 1
$evenIndex = $group[1]; //start with index 2
echo "odd index: "
. implode('/', $oddIndex)
. "\neven index: "
. implode('/', $evenIndex)
. "\n";
You can split the array into groups using % on loop index. Put each group in separate array. Here is example:
<?php
$string = "1/2/3/4/5/6";
$splitted = explode("/",$string);
$group_odd = array(); ## all odd elements of $splitted come here
$group_even = array(); ## all even elements of $splitted come here
for ($index = 0; $index < count($splitted); ++$index) {
## if number is divided by 2 with rest then it's odd
## but we've started calculation from 0, so we need to add 1
if (($index+1) % 2) {
$group_odd[] = $splitted[$index];
}
else {
$group_even[] = $splitted[$index];
}
}
echo implode('/', $group_odd), "<br />"; ## outputs "1/3/5<br />"
echo implode('/', $group_even), "<br />"; ## outputs "2/4/6<br />"
print_r($group_odd);
print_r($group_even);
?>
Based on their position? So, split based on the evenness/oddness of their index in the array?
Something like this?
<?php
$string = "1/2/3/4/5/6";
list( $evenKeys, $oddKeys ) = array_split_custom( explode( '/', $string ) );
echo '<pre>';
print_r( $evenKeys );
print_r( $oddKeys );
function array_split_custom( array $input )
{
$evens = array();
$odds = array();
foreach ( $input as $index => $value )
{
if ( $index & 1 )
{
$odds[] = $value;
} else {
$evens[] = $value;
}
}
return array( $evens, $odds );
}