find same numbers in between -to- and group them - php

Here I want to find the same numbers in between - -
For example : Here (6-85-,7-85-,8-113-,) same numbers are 85. I want to find them and group them (add comma) like this
6,7
8
Another example :
2-1-,1-29-,4-57-,5-57-,6-85-,7-85-,8-113-,
2
1
4,5
6,7
8
Is there any way to do this in php? I have searched on here and other forums but never get any idea..

This is how I would do it:
$collect = array();
$s="2-1-,1-29-,4-57-,5-57-,6-85-,7-85-,8-113-,";
$a = explode(',', $s);
foreach($a as $v){
$m = explode('-',$v);
if( count($m) >= 2 ){
$collect[$m[1]][] = $m[0];
}
}
foreach($collect as $match){
echo implode(',', $match)."\n";
}

Related

PHP array get the different number

I have the following array:
$array = [2,2,5,2,2];
I would like to get the number which is different from the others, for example all the numbers are 2 except the number 5. So Is there anyway to get the different number using any array method or better solution? My solution is:
$array = [2,2,5,2,2];
$array1 = [4,4,4,6,4,4,4];
$element = -1;
$n = -1;
$count = 0;
for($i=0; $i<count($array1); $i++) {
if($element !== $array1[$i] && $element !== -1 & $count==0) {
$n = $array1[$i];
$count++;
}
$element = $array1[$i];
}
dd($n);
You can use array_count_values for group and count same value like:
$array = [2,2,5,2,2];
$countarray = array_count_values($array);
arsort($countarray);
$result = array_keys($countarray)[1]; // 5
Since you only have two numbers, you will always have the number with the least equal values ​​in second position
Reference:
array_count_values
array_keys
A small clarification, for safety it is better to use arsort to set the value in second position because if the smallest number is in first position it will appear as the first value in the array
Sorting Arrays
You can user array_count_values which returns array with item frequency.
Then use array_filter to filter out data as follow:
$arrayData = [2,2,2,5];
$filterData = array_filter(array_count_values($arrayData), function ($value) {
return $value == 1;
});
print_r($filterData);
Inside array_filter(), return $value == 1 means only get the data with 1 frequency and thus filter out the other data.
<?php
function UniqueAndDuplicat($array){
$counts = array_count_values($array);
foreach ($counts as $number => $count) {
print $number . ' | ' . ($count > 1 ? 'Duplicate value ' : 'Unique value ') . "\n";
}
}
$array1 = [2,2,5,2,2];
$array2 = [4,4,4,6,4,4,4];
UniqueAndDuplicat($array1);
//output: 2 | duplicate value 5 | Unique value
UniqueAndDuplicat($array2);
//output: 4 | duplicate value 5 | Unique value
?>
Use this function to reuse this you just call this function and pass an Array to this function it will give both unique and duplicate numbers.
If you want to return only Unique number then use the below code:
<?php
function UniqueAndDuplicat($array){
$counts = array_count_values($array);
foreach ($counts as $number => $count) {
if($count == 1){
return $number;
}
}
}
$array1 = [2,2,5,2,2];
$array2 = [4,4,4,6,4,4,4];
echo UniqueAndDuplicat($array1); // 5
echo "<br>";
echo UniqueAndDuplicat($array2); // 6
?>

How to remove a specific line break between two lines in a string without removing other breaks ? php

I have a string like this and I want to remove the break of the line if the number in the line doesn't match the line number. How is it possible ?
It's my string :
1 //line1
2 //line2
3 //line3
5 //line4
4 //line5
5 //line6
6 //line7
For example in this string the line 4's value is 5 so I must omit its break and make it like
1
2
3 5
4
5
6
Here is my code :
foreach(preg_split("/((\r?\n)|(\r\n?))/", $string) as $line){
if ($line != __LINE__){
//remove the break and I'm stuck here...
}
}
Any solution ? Thanks in advance...
UPDATE :
I've also tried converting it into an array like below :
$linesArray = explode("\n", $string);
foreach($linesArray as $key => $val){
if(($key+1) != $val){
$output[$key] = $linesArray[$key-1].' '.$val.' '.$linesArray[$key+1];
$o_line++;
}else{
$output[$key] = $val;
$o_line++;
}
}
but it's not working or I'm wrong somewhere...
I have written a code for you. Let me know if it meets your goal.
$string = "1\n2\n3\n5\n4\n6\n5";
$line = explode("\n", $string);
$line2 = "";
$n = 1;
foreach($line as $v) {
if($n != $v) continue;
$line2 .= $v."\n";
$n++;
}
echo $line2;
May be this line has issues -
$output[$key] = $linesArray[$key-1].' '.$val.' '.$linesArray[$key+1];
// as key is 0 for first iteration, so it will be like $linesArray[-1]

PHP: Remove third item in 4 items comma list "1,2,3,4" [duplicate]

This question already has answers here:
Deleting an element from an array in PHP
(25 answers)
Closed 9 years ago.
How can I delete the 3 in "1,2,3,4"?
Dirty hack: Slice the sliced arrays and join them again.
$s = "1,2,3,4";
$array = explode(',', $s);
$a = array_splice($array, 0, -2);
$b = array_splice($array, 1, 1);
$s = implode(',', $a).','.implode($b);
echo $s; // 1,2,4
Test: http://codepad.org/WeDLKvEE
OK. How about using strpos and instr? Find the second comma and the third one.
$s = "1,2,3,4";
$array = explode(',', $s);
unset($array[2]);
$Arr = array_values($array);
print_r($Arr);
demo : https://eval.in/85585
How about this, by this you do not depend on the position of the string rather can wipe out by value.
$s = "1,2,3,4";
$array = explode(",",$s);
$val = 3 ;
$key = array_search($val,$array);
if($key!==false){
unset($array[$key]);
}
echo implode(",",$array); // 1,2,4

how to order in while loop?

I want to get the count of characters from the following words in the string. For example, if my input is I am John then the output must be like this:
9 // count of 'I am John'
4 // count of 'I am'
1 // count of 'I'
I use the code like this in PHP for this process:
$string = 'I am John';
$words = explode(' ',$string);
$count_words = count($words);
$i =0;
while ($i<$count_words){
if($i==0) {
$words_length[$i] = strlen($words[$i]);
} else {
$words_length[$i] = strlen($words[$i])+1+$words_length[$i-1];
}
echo $words_length[$i]."<br>";
$i++;
}
But it return the output like this:
1
4
9
Why ? Where is my error ? How can I change the ordering ? What does my code must be like ?
Thanks in advance!
If you simply want to have the output in reverse order use array_reverse:
print_r(array_reverse($words_length));
Your problem is that you're looping through the words left to right. You can't output the full length right to left, because each one depends on the words to it's left.
You could take the echo out of the loop, and print the values after all have been calculated.
$string = 'I am John';
$words = explode(' ',$string);
$count_words = count($words);
$i =0;
while ($i<$count_words){
if($i==0) {
$words_length[$i] = strlen($words[$i]);
} else {
$words_length[$i] = strlen($words[$i])+1+$words_length[$i-1];
}
$i++;
}
print implode('<br />', array_reverse($words_length));
The quickest fix is to add print_r(array_reverse($words_length)); after the loop
You may use foreach and array_reverse to get the array values:
foreach(array_reverse($words_length) as $val){
echo $val;
}

"Unfolding" a String

I have a set of strings, each string has a variable number of segments separated by pipes (|), e.g.:
$string = 'abc|b|ac';
Each segment with more than one char should be expanded into all the possible one char combinations, for 3 segments the following "algorithm" works wonderfully:
$result = array();
$string = explode('|', 'abc|b|ac');
foreach (str_split($string[0]) as $i)
{
foreach (str_split($string[1]) as $j)
{
foreach (str_split($string[2]) as $k)
{
$result[] = implode('|', array($i, $j, $k)); // more...
}
}
}
print_r($result);
Output:
$result = array('a|b|a', 'a|b|c', 'b|b|a', 'b|b|c', 'c|b|a', 'c|b|c');
Obviously, for more than 3 segments the code starts to get extremely messy, since I need to add (and check) more and more inner loops. I tried coming up with a dynamic solution but I can't figure out how to generate the correct combination for all the segments (individually and as a whole). I also looked at some combinatorics source code but I'm unable to combine the different combinations of my segments.
I appreciate if anyone can point me in the right direction.
Recursion to the rescue (you might need to tweak a bit to cover edge cases, but it works):
function explodinator($str) {
$segments = explode('|', $str);
$pieces = array_map('str_split', $segments);
return e_helper($pieces);
}
function e_helper($pieces) {
if (count($pieces) == 1)
return $pieces[0];
$first = array_shift($pieces);
$subs = e_helper($pieces);
foreach($first as $char) {
foreach ($subs as $sub) {
$result[] = $char . '|' . $sub;
}
}
return $result;
}
print_r(explodinator('abc|b|ac'));
Outputs:
Array
(
[0] => a|b|a
[1] => a|b|c
[2] => b|b|a
[3] => b|b|c
[4] => c|b|a
[5] => c|b|c
)
As seen on ideone.
This looks like a job for recursive programming! :P
I first looked at this and thought it was going to be a on-liner (and probably is in perl).
There are other non-recursive ways (enumerate all combinations of indexes into segments then loop through, for example) but I think this is more interesting, and probably 'better'.
$str = explode('|', 'abc|b|ac');
$strlen = count( $str );
$results = array();
function splitAndForeach( $bchar , $oldindex, $tempthread) {
global $strlen, $str, $results;
$temp = $tempthread;
$newindex = $oldindex + 1;
if ( $bchar != '') { array_push($temp, $bchar ); }
if ( $newindex <= $strlen ){
print "starting foreach loop on string '".$str[$newindex-1]."' \n";
foreach(str_split( $str[$newindex - 1] ) as $c) {
print "Going into next depth ($newindex) of recursion on char $c \n";
splitAndForeach( $c , $newindex, $temp);
}
} else {
$found = implode('|', $temp);
print "Array length (max recursion depth) reached, result: $found \n";
array_push( $results, $found );
$temp = $tempthread;
$index = 0;
print "***************** Reset index to 0 *****************\n\n";
}
}
splitAndForeach('', 0, array() );
print "your results: \n";
print_r($results);
You could have two arrays: the alternatives and a current counter.
$alternatives = array(array('a', 'b', 'c'), array('b'), array('a', 'c'));
$counter = array(0, 0, 0);
Then, in a loop, you increment the "last digit" of the counter, and if that is equal to the number of alternatives for that position, you reset that "digit" to zero and increment the "digit" left to it. This works just like counting with decimal numbers.
The string for each step is built by concatenating the $alternatives[$i][$counter[$i]] for each digit.
You are finished when the "first digit" becomes as large as the number of alternatives for that digit.
Example: for the above variables, the counter would get the following values in the steps:
0,0,0
0,0,1
1,0,0 (overflow in the last two digit)
1,0,1
2,0,0 (overflow in the last two digits)
2,0,1
3,0,0 (finished, since the first "digit" has only 3 alternatives)

Categories