Unable to resolve the array_diff issue - php

$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 */ }

Related

Find the two longest strings separated by dash in 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];

php need assistance with regular expression

I want to parse and expand the given strings in PHP.
From
0605052&&-5&-7&-8
0605052&&-4&-7
0605050&&-2&-4&-6&-8
To
0605052, 0605053 ,0605054 ,0605055, 0605057, 0605058
0605052,0605053,0605054,0605057
0605050,0605051,0605052,0605054,0605056,0605058
can someone help me with that? thanks in advance!
Your question is not very clear, but I think you mean a solution like this:
Edited: Now the hole ranges were shown and not only the specified numbers.
<?php
$string = "0605052&&-5&-7&-8";
$test = '/^([0-9]+)\&+/';
preg_match($test, $string, $res);
if (isset($res[1]))
{
$nr = $res[1];
$test = '/\&\-([0-9])/';
preg_match_all($test, $string, $res);
$result[] = $nr;
$nrPart = substr($nr, 0, -1);
$firstPart = substr($nr, -1);
if (isset($res[1]))
{
foreach ($res[1] as &$value)
{
if ($firstPart !== false)
{
for ($i=$firstPart+1; $i<=$value; $i++)
{
$nr = $nrPart . $i;
$result[] = $nr;
}
$firstPart = false;
}
else
{
$nr = $nrPart . $value;
$result[] = $nr;
$firstPart = $value;
}
}
}
var_dump($result);
}
?>
This delivers:
result[0] = "0605052"
result[1] = "0605053"
result[2] = "0605054"
result[3] = "0605055"
result[4] = "0605057"
result[5] = "0605058"
I think a multi step approach is the best thing to do here.
E.g. take this as an example 0605052&&-5&-7&-8:
Split at -. The result will be 0605052&&, 5&, 7&, 8
The first result 0605052&& will help you create your base. Simply substring the numbers by finding first occurence of & and substring to the next to last number. Result will be 060505. You will also need the last number, so get it as well (which is 2 in this case).
Get the remaining ends now, all \d& are simple to get, simply take the first character of the string (or if those can be more than one number, use substring with first occurence of & approach again).
The last number is simple: it is 8.
Now you got all important values. You can generate your result:
The last number from 2., all numbers from 3. and the number from 4. together with your base are the first part. In addition, you need to generate all numbers from the last number of 2. and the first result of 3. in a loop by a step of 1 and append it to your base.
Example Code:
<?php
$str = '0605052&&-5&-7&-8';
$split = explode('-', $str);
$firstAmpBase = strpos($split[0], '&');
$base = substr($split[0], 0, $firstAmpBase - 1);
$firstEnd = substr($split[0], $firstAmpBase - 1, 1);
$ends = [];
$firstSingleNumber = substr($split[1], 0, strpos($split[1], '&'));
for ($i = $firstEnd; $i < $firstSingleNumber; $i++) {
array_push($ends, $i);
}
array_push($ends, $firstSingleNumber);
for ($i = 2; $i < count($split) - 1; $i++) {
array_push($ends, substr($split[$i], 0, strpos($split[$i], '&')));
}
array_push($ends, $split[count($split) - 1]);
foreach ($ends as $end) {
echo $base . $end . '<br>';
}
?>
Output:
0605052
0605053
0605054
0605055
0605057
0605058

php the best way to split string containing pairs of values

i have a string in the following format:
$str='a1_b1,a2_b2,a3_b3'
where a and b - some positive numbers. i need to split it to get two strings in format:
'a1,a2,a3' and 'b1,b2,b3'
the very primitive way would be:
$temp=explode(',', $str);
$str1='';
$str2='';
for($i=0;$i<count($temp);$i++){
$temp2=explode('_',$temp[$i]);
$str1.=$temp2[0].',';
$str2.=$temp2[1].',';
}
is it possible to do it more intelligent then just explode in loop?
Not much different from accepted answer but doing it with fewer code
<?php
$str = 'a1_b1,a2_b2,a3_b3';
$temp=explode(',', $str);
foreach($temp as $tem)
list($str_a[], $str_b[])=explode('_',$tem);
$str1 = implode(',', $str_a);
$str2 = implode(',', $str_b);
Probably the easiest way (which also happens to use the least amount of code and no loops) is to make use of PHP's parse_str() function:
// Assuming $str = 'a1_b1,a2_b2,a3_b3'
$str = str_replace([',', '_'], ['&', '='], $str);
parse_str($str, $arr);
// Your key/value pairs are now in $arr
$keys = implode(',', array_keys($arr));
$values = implode(',', array_values($arr));
Of course, parse_str() expects the standard foo=bar&baz=boz format, so if possible, you should use that format instead of foo_bar,baz_boz to save yourself a step. But, if that's not possible, then you can simply use str_replace() like I did above to make the appropriate substitutions.
Note: I used PHP 5.4 short array syntax [...]. If you're using < PHP 5.4, change it to array(...) instead.
The best way would be to organize the formatting of the string so that it doesnt come to this stage where you need to do this. But I'm assuming that you cant do that, therefore posting this question here,
What you did is a good way to do this unless you want to use regex.
$str = 'a1_b1,a2_b2,a3_b3' ;
$exp = explode(',', $str);
$a = array();
$b = array();
foreach($exp as $i)
{
$sep = explode('_', $i);
$a[] = $sep[0];
$b[] = $sep[1];
}
// at this point a and b are arrays so if you want to do better things to the data
// you can use arrays instead of manually concatenating the items with commas
$a_str = implode(',', $a); // a1,a2,a2
$b_str = implode(',', $b); // b1,b2,b2
$temp=explode(',', $str);
$str1='';
$str2='';
$str_a = array();
$str_b = array();
for($i=0;$i<count($temp);$i++){
$temp2=explode('_',$temp[$i]);
$str_a[]=$temp2[0];
$str_b[]=$temp2[1];
}
$str1 = implode(',', $str_a);
$str2 = implode(',', $str_b);
Oh, this is nothing more intelligent...
I can't really think of a better way of doing it. The best thing would be to not get in a situation where you need to do this in the first place but what can we do?
Just to provide another (not better) way of doing the same thing, you can use strtok.
$str='a1_b1,a2_b2,a3_b3';
$tok = strtok($str, "_,");
$i = 0;
$a = array();
$b = array();
while ($tok !== false) {
if ($i++ %2) $b[] = $tok;
else $a[] = $tok;
$tok = strtok("_,");
}
echo implode(',', $a); //a1,a2,a3
echo implode(',', $b); //b1,b2,b3
Your way is more clear and easier to understand, so I'd just stick with it.
Assuming PHP >= 5.3.0:
$str = 'a1_b1,a2_b2,a3_b3';
$array = array_map(function($n) { return explode("_", $n); }, explode(",", $str));
$aString = implode(",", array_map(function($n) { return $n[0]; }, $array));
$bString = implode(",", array_map(function($n) { return $n[1]; }, $array));
var_dump($aString);
var_dump($bString);
Output:
string 'a1,a2,a3' (length=8)
string 'b1,b2,b3' (length=8)
Still looping strictly speaking, but fancier :)
$str = 'a1_b1,a2_b2,a3_b3' ;
$arr = preg_split("/[\s,_]/" , $str);
$str1 = $str2 = '';
for($i=0; $i<count($arr); $i++) {
$str1 .= $arr[$i] ;
if(isset($arr[$i+1]))
$str2 .= $arr[$i+1];
if(isset($arr[$i+2])) {
$str1 .= ',';
$str2 .= ',';
}
$i++;
}

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

Capitalize every other letter within exploded array

Initially i had posted a question to find a solution to capitalize every other letter in a string. Thankfully Alex # SOF was able to offer a great solution, however ive been unable to get it to work with an array... To be clear what im trying to do in this case is explode quotes, capitalize every other letter in the array then implode them back.
if (stripos($data, 'test') !== false) {
$arr = explode('"', $data);
$newStr = '';
foreach($arr as $index => $char) {
$newStr .= ($index % 2) ? strtolower($char) : strtoupper($char);
}
$data = implode('"', $arr);
}
Using the anonymous function requires >= PHP 5.3. If not, just make the callback a normal function. You could use create_function(), but it is rather ugly.
$str = '"hello" how you "doing?"';
$str = preg_replace_callback('/"(.+?)"/', function($matches) {
$newStr = '';
foreach(str_split($matches[0]) as $index => $char) {
$newStr .= ($index % 2) ? strtolower($char) : strtoupper($char);
}
return $newStr;
}, $str);
var_dump($str);
Output
string(24) ""hElLo" how you "dOiNg?""
CodePad.
If you want to swap the case, swap the strtolower() and strtoupper() calls.
Is this what you're looking for?
foreach($data as $key => $val)
{
if($key%2==0) $data[$key] = strtoupper($data[$key]);
else $data[$key] = strtolower($data[$key]);
}
Or.... instead of using regular expression you could just not even use the explode method, and go with every other character and capitalize it. Here is an example:
$test = "test code here";
$count = strlen($test);
echo "Count = " . $count . '<br/>';
for($i = 0; $i < $count; $i++)
{
if($i % 2 == 0)
{
$test[$i] = strtolower($test[$i]);
}
else
{
$test[$i] = strtoupper($test[$i]);
}
}
echo "Test = " . $test;
The secret lies in the modulus operator. ;)
Edit: Dang, I just noticed the post above me by Jordan Arsenault already submitted this answer... I got stuck on the regex answer I missed that :-/ sorry Jordan, you were already on point.

Categories