Find the two longest strings separated by dash in PHP - php

I want to define two new variables as the longest strings from a given string. if the string does not contain any dashes, just choose it for both.
Example:
$orig=`welcome-to-your-world`
$s1=`welcome`
$s2=`world`
$orig=`welcome-to-your-holiday`
$s1=`welcome` // order not important
$s2=`holiday`// order not important
$orig=`welcome`
$s1=`welcome`
$s2=`welcome`

Solution with explode and sorting result array by length of words:
$orig = 'welcome-to-your-world';
$parts = explode('-', $orig);
if (1 < count($parts)) {
usort($parts, function($a, $b) { return strlen($a) < strlen($b); });
$s1 = array_shift($parts);
$s2 = array_shift($parts);
} else {
$s1 = $s2 = $orig;
}
echo $s1 . PHP_EOL . $s2;
Fiddle here.

It seems like your string is in dash-case (words in lower case separated by dashes).
So, you can do the following:
// convert origin in an array
$origin_array = explode("-", $origin);
//retrivies the first element from array
$s1 = '';
$s2 = '';
// get the longest string
foreach($origin_array as $word) {
if(strlen($word) > strlen($s1)) {
$s1 = $word;
}
}
// remove the longest word from the array
$origin_array = array_diff($origin_array, [$s1]);
// get the second longest string
foreach($origin_array as $word) {
if(strlen($word) > strlen($s2)) {
$s2 = $word;
}
}
I think that solves your problem. Hope that helps!
Note: This method is not efficient because it runs foreach twice. The other answer is better if you care about performance.

$orig = 'welcome-to-your-world';
$array = explode('-', $orig);
$lengths = array_map('strlen', $array);
$s1key = array_search(max($lengths), $lengths);
$s1 = $array[$s1key];
unset ($array[$s1key], $lengths[$s1key]);
$s2key = array_search(max($lengths), $lengths);
$s2 = $array[$s2key];

Related

Dynamic explosion with specific character

I am trying to extract a string in php and convert them to comma separated strings
Here are some sample string I am working with and the results I need:
input :
G1_C2_S3_T5 or G4_C5_S4_T7_I6_H3
Result must be :
G1,G1_C2,G1_C2_S3,G1_C2_S3_T5
or
G4,G4_C5,G4_C5_S4,G4_C5_S4_T7,G4_C5_S4_T7_I6,G4_C5_S4_T7_I6_H3
Input length can be dynamic for comma separation
Is this correct :
$arr = explode("_", $string, 2);
$first = $arr[0];
How can i do that in php?
Something like this should work, $string is the string you are working with
//explode by underscore
$parts = explode('_', $string);
$c = [];
//do until nothing else to pop from array
while (!empty($parts)) {
$c[] = implode('_', $parts);
//will pop element from end of array
array_pop($parts);
}
//reverse
$c = array_reverse($c);
//glue it with comma
echo implode(',', $c);
You should notice that the number of underscore-separated values in your initial string e.g. G4_C5_S4_T7_I6_H3 (6) is equal to the number of comma-separated values in your desired string e.g. G4,G4_C5,G4_C5_S4,G4_C5_S4_T7,G4_C5_S4_T7_I6,G4_C5_S4_T7_I6_H3 (6). So we'll use this number in our first loop $end = count($parts).
$str = "G4_C5_S4_T7_I6_H3";
$newstr = '';
$parts = explode('_', $str);
$comma = '';
for ($i = 0, $end = count($parts); $i < $end; $i++) {
$newstr .= $comma;
$underscore = '';
// build underscore-separated value
// index i is used to indicate up which value to stop at for each iteration
for ($j = 0; $j <= $i; $j++) {
$newstr .= $underscore . $parts[$j];
// set underscore after the first iteration of the loop
$underscore = '_';
}
// set comma after the first iteration of the loop
$comma = ',';
}
echo $newstr; // G4,G4_C5,G4_C5_S4,G4_C5_S4_T7,G4_C5_S4_T7_I6,G4_C5_S4_T7_I6_H3
The explosion is easy:
$parts = explode('_', $string);
Now you get a $parts array like [ 'G1', 'C2', 'S3', 'T5' ].
You want to convert this to an array so that each item is the concatenation of that item and every other item before it:
$prev = [ ];
array_walk(
$parts,
function(&$value) use (&$prev) {
$prev[] = $value;
$value = implode('_', $prev);
}
);
Now $parts holds the elements:
print implode(', ', $parts);
yields
G1, G1_C2, G1_C2_S3, G1_C2_S3_T5

I want to filter a string and to make an array using php

This is my sample string (this one has five words; in practice, there may be more):
$str = "I want to filter it";
Output that I want:
$output[1] = array("I","want","to","filter","it");
$output[2] = array("I want","want to","to filter","filter it");
$output[3] = array("I want to","want to filter","to filter it");
$output[4] = array("I want to filter","want to filter it");
$output[5] = array("I want to filter it");
What I am trying:
$text = trim($str);
$text_exp = explode(' ',$str);
$len = count($text_exp);
$output[$len][] = $text; // last element
$output[1] = $text_exp; // first element
This gives me the first and the last arrays. How can I get all the middle arrays?
more generic solution that works with any length word:
$output = array();
$terms = explode(' ',$str);
for ($i = 1; $i <= count($terms); $i++ )
{
$round_output = array();
for ($j = 0; $j <= count($terms) - $i; $j++)
{
$round_output[] = implode(" ", array_slice($terms, $j, $i));
}
$output[] = $round_output;
}
You can do that easily with regular expressions that give you the most flexibility. See below for the way that supports dynamic string length and multiple white characters between words and also does only one loop which should make it more efficient for long strings..
<?php
$str = "I want to filter it";
$count = count(preg_split("/\s+/", $str));
$results = [];
for($i = 1; $i <= $count; ++$i) {
$expr = '/(?=((^|\s+)(' . implode('\s+', array_fill(0, $i, '[^\s]+')) . ')($|\s+)))/';
preg_match_all($expr, $str, $matches);
$results[$i] = $matches[3];
}
print_r($results);
You can use a single for loop and if conditions to do
$str = "I want to filter it";
$text = trim($str);
$text_exp = explode(' ',$str);
$len = count($text_exp);
$output1=$text_exp;
$output2=array();
$output3=array();
$output4=array();
$output5=array();
for($i=0;$i<count($text_exp);$i++)
{
if($i+1<count($text_exp) && $text_exp[$i+1]!='')
{
$output2[]=$text_exp[$i].' '.$text_exp[$i+1];
}
if($i+2<count($text_exp) && $text_exp[$i+2]!='')
{
$output3[]=$text_exp[$i].' '.$text_exp[$i+1].' '.$text_exp[$i+2];
}
if($i+3<count($text_exp) && $text_exp[$i+3]!='')
{
$output4[]=$text_exp[$i].' '.$text_exp[$i+1].' '.$text_exp[$i+2].' '.$text_exp[$i+3];
}
if($i+4<count($text_exp) && $text_exp[$i+4]!='')
{
$output5[]=$text_exp[$i].' '.$text_exp[$i+1].' '.$text_exp[$i+2].' '.$text_exp[$i+3].' '.$text_exp[$i+4];
}
}

Modify numbers inside a string PHP

I have a string like this:
$string = "1,4|2,64|3,0|4,18|";
Which is the easiest way to access a number after a comma?
For example, if I have:
$whichOne = 2;
If whichOne is equal to 2, then I want to put 64 in a string, and add a number to it, and then put it back again where it belongs (next to 2,)
Hope you understand!
genesis'es answer with modification
$search_for = 2;
$pairs = explode("|", $string);
foreach ($pairs as $index=>$pair)
{
$numbers = explode(',',$pair);
if ($numbers[0] == $search_for){
//do whatever you want here
//for example:
$numbers[1] += 100; // 100 + 64 = 164
$pairs[index] = implode(',',$numbers); //push them back
break;
}
}
$new_string = implode('|',$pairs);
$numbers = explode("|", $string);
foreach ($numbers as $number)
{
$int[] = intval($number);
}
print_r($int);
$string = "1,4|2,64|3,0|4,18|";
$coordinates = explode('|', $string);
foreach ($coordinates as $v) {
if ($v) {
$ex = explode(',', $v);
$values[$ex[0]] = $ex[1];
}
}
To find the value of say, 2, you can use $whichOne = $values[2];, which is 64
I think it is much better to use the foreach like everyone else has suggested, but you could do it like the below:
$string = "1,4|2,64|3,0|4,18|";
$whichOne = "2";
echo "Starting String: $string <br>";
$pos = strpos($string, $whichOne);
//Accomodates for the number 2 and the comma
$valuepos = substr($string, $pos + 2);
$tempstring = explode("|", $valuepos);
$value = $tempstring[0]; //This will ow be 64
$newValue = $value + 18;
//Ensures you only replace the index of 2, not any other values of 64
$replaceValue = "|".$whichOne.",".$value;
$newValue = "|".$whichOne.",".$newValue;
$string = str_replace($replaceValue, $newValue, $string);
echo "Ending String: $string";
This results in:
Starting String: 1,4|2,64|3,0|4,18|
Ending String: 1,4|2,82|3,0|4,18|
You could run into issues if there is more than one index of 2... this will only work with the first instance of 2.
Hope this helps!
I know this question is already answered, but I did one-line solution (and maybe it's faster, too):
$string = "1,4|2,64|3,0|4,18|";
$whichOne = 2;
$increment = 100;
echo preg_replace("/({$whichOne},)(\d+)/e", "'\\1'.(\\2+$increment)", $string);
Example run in a console:
noice-macbook:~/temp% php 6642400.php
1,4|2,164|3,0|4,18|
See http://us.php.net/manual/en/function.preg-replace.php

Longest word in a string

How can I get the longest word in a string?
Eg.
$string = "Where did the big Elephant go?";
To return "Elephant"
Loop through the words of the string, keeping track of the longest word so far:
<?php
$string = "Where did the big Elephant go?";
$words = explode(' ', $string);
$longestWordLength = 0;
$longestWord = '';
foreach ($words as $word) {
if (strlen($word) > $longestWordLength) {
$longestWordLength = strlen($word);
$longestWord = $word;
}
}
echo $longestWord;
// Outputs: "Elephant"
?>
Can be made a little more efficient, but you get the idea.
Update: Here is another even shorter way (and this one is definitely new ;)):
function reduce($v, $p) {
return strlen($v) > strlen($p) ? $v : $p;
}
echo array_reduce(str_word_count($string, 1), 'reduce'); // prints Elephant
Similar as already posted but using str_word_count to extract the words (by just splitting at spaces, punctuation marks will be counted too):
$string = "Where did the big Elephant go?";
$words = str_word_count($string, 1);
function cmp($a, $b) {
return strlen($b) - strlen($a);
}
usort($words, 'cmp');
print_r(array_shift($words)); // prints Elephant
How about this -- split on spaces, then sort by the string length, and grab the first:
<?php
$string = "Where did the big Elephant go?";
$words = explode(' ', $string);
usort($words, function($a, $b) {
return strlen($b) - strlen($a);
});
$longest = $words[0];
echo $longest;
Edit If you want to exclude punctuation, for example: "Where went the big Elephant?", you could use preg_split:
$words = preg_split('/\b/', $string);
Here is another solution:
$array = explode(" ",$string);
$result = "";
foreach($array as $candidate)
{
if(strlen($candidate) > strlen($result))
$result = $candidate
}
return $result;
This is a quite useful function when dealing with text so it might be a good idea to create a PHP function for that purpose:
function longestWord($txt) {
$words = preg_split('#[^a-z0-9áéíóúñç]#i', $txt, -1, PREG_SPLIT_NO_EMPTY);
usort($words, function($a, $b) { return strlen($b) - strlen($a); });
return $words[0];
}
echo longestWord("Where did the big Elephant go?");
// prints Elephant
Test this function here: http://ideone.com/FsnkVW
A possible solution would be to split the sentence on a common separator, such as spaces, and then iterate over each word, and only keep a reference to the largest one.
Do note that this will find the first largest word.
<?php
function getLargestWord($str) {
$strArr = explode(' ', $str); // Split the sentence into an word array
$lrgWrd = ''; // initial value for comparison
for ($i = 0; $i < count($strArr); $i++) {
if (strlen($strArr[$i]) > strlen($lrgWrd)) { // Word is larger
$lrgWrd = $strArr[$i]; // Update the reference
}
}
return $lrgWrd;
}
// Example:
echo getLargestWord('Where did the big Elephant go?');
?>
$string ='Where did the big Elephant';
function longestWord($str) {
$str.=" ";
$ex ="";
$max ="";
for($i = 0; $i < strlen($str); $i++)
{
if($str[$i]==" ")
{
if(strlen($ex) > strlen($max))
$max = $ex;
$ex ="";
}else
{
$ex.=$str[$i];
}
}
return $max;
}
echo longestWord($string);

Unable to resolve the array_diff issue

$j[0]='is';
$j[1]='for';
$diff = array_diff($uniqdesc, $j);
foreach($diff as $find){
echo $find."</br>";
$uniquedesc is an array from a string of words.
I need to print out all the uncommon words. The above code is working fine and eliminating 'is' 'for'
Now I stored all the common words in a text file. And I need to eliminate those common words from any string of words.
But the code does not seem to work. How to solve this?
$common = file_get_contents('commonwords.txt');
$commonArray = explode(" ",$common);
sort($commonArray);
$q=0;
array_unique($commonArray);
$jay=array_unique($commonArray);
foreach($jay as $k){
$j[$q]=(string)$k;
$q=$q+1;
}
$q=0;
for($q=0;$q<20;$q++)
{
echo $j[$q];// This is for testing. It printed the first 20 strings correctly.
}
$diff = array_diff($uniqdesc, $j);
foreach($diff as $find){
echo $find."</br>";
It may be an issue with there being whitespace on either side of the text from your file. Furthermore, it may also be an issue that array_diff() distinguishes between word cases.
For example:
$a = array("word");
$b = array("WORD");
$c = array_diff($a, $b);
// $c = array("WORD", "word");
You may need to convert $uniqdesc to contain only lower or upper case characters.
If you try the following code and it doesn't work either, it's probably a text upper/lower case mismatch that's causing the problems:
$words = file_get_contents("commonwords.txt");
$words = explode(" ", $words);
for ($i = 0, $sz = count($words); $i < $sz; $i++) { $words[$i] = trim($words[$i]); }
$words = array_unique($words);
$diff = array_diff($uniqdesc, $words);
foreach ($diff as $find) { /* Do stuff */ }

Categories