Determining duplicate letter counts between an array of strings - php

I have an array of strings of random letters, and I need to know which letters are consistent between the array members. The count of the letters are important.
My method right now is loop through the array, doing a split, then looping through the spitted string to count the occurrences of each letter, then update the array with letter => count
Then do an array_reduce that creates a new array of members who only occur in all arrays. But, it's not working.
<?
$a[] = "emaijuqqrauw";
$a[] = "aaeggimqruuz";
$a[] = "aabimqrtuuzw";
$a[] = "aacikmqruuxz";
$a[] = "aacikmqruuxz";
$a[] = "aaciimqruuxy";
foreach($a as $b){
$n = str_split($b, 1);
foreach($n as $z){
$arr[$z] = substr_count($b, $z);
}
ksort($arr);
$array[] = $arr;
unset($arr);
}
$n = array_reduce($array, function($result, $item){
if($result === null){
return $item;
}else{
foreach($item as $key => $val){
if(isset($result[$key])){
$new[$key] = $val;
}
}
return $new;
}
});
foreach($n as $key => $val){
echo str_repeat($key, $val);
}
This returns aaiimqruu - which is kinda right, but there's only 2 i's in the last element of the array. There's only one i in the rest. I'm not sure how to break that down farther and get it to return aaimqruu- which I'll then pop into a SQL query to find a matching word, aquarium

There's array_intersect(), which is most likely what you'd want. Given your $a array, you'd do something like:
$a = array(.... your array...);
$cnt = count($a);
for($i = 0; $i < $cnt; $i++) {
$a[$i] = explode('', $a[$i]); // split each string into array of letters
}
$common = $a[0]; // save the first element
for($i = 1; $i < $cnt; $i++) {
$common = array_intersect($common, $a[$i]);
}
var_dump($common);

How about you do it this way? Finds out the occurrence of an item throughout the array.
function findDuplicate($string, $array) {
$count = 0;
foreach($array as $item) {
$pieces = str_split($item);
$pcount= array_count_values($pieces);
if(isset($pcount[$string])) {
$count += $pcount[$string];
}
}
return $count;
}
echo findDuplicate("a",$a);
Tested :)
Gives 12, using your array, which is correct.
Update
My solution above already had your answer
$pieces = str_split($item);
$pcount= array_count_values($pieces);
//$pcount contains, every count like [a] => 2

Seems like array_reduce is the best function for what this purpose, however I just didn't think of adding a conditional to give me the desired effect.
$new[$key] = ($result[$key] > $val) ? $val : $result[$key];
to replace
$new[$key] = $val;
did the trick.

Related

All Combinations of one Array with 2 connectors

My problem is relatively simple but I cannot figure it out a reasonable algorithm by myself
I have an array which can be any length (n>=2), and I want to connect the elements with 2 separators ( '_' and '+' ):
So for example when my array has 2 elements [0,1] the result would be
[0_1, 0+1]
For 3 elements [0,1,2]
0_1_2,
0+1+2,
0+1_2,
0_1+2,
0_2+1
For 4 elements [0,1,2,3]
0_1_2_3,
0+1+2+3,
0+1_2_3,
0_1+2_3,
0_1_2+3,
0_2+1+3,
0_2+1_3,
0_3+1+2,
0_3+1_2
For 5 elements [0,1,2,3,4]
0_1_2_3_4,
0+1_2_3_4,
0_1+2_3_4,
0_1_2+3_4,
0_1_2_3+4,
0+1+2+3+4,
0_2+1+3+4,
0_2+1_3_4,
0_2+1+3_4,
0_2+1_3+4,
...
I hope this explanation is somewhat clear.
Not sure if this hits spec, but its a start:
$new = [];
$arr = [1,2,3,4,5];
for($i=0;$i<count($arr);$i++) {
$new[] = implode("_",$arr);
$arr[] = array_shift($arr);
}
foreach($new as $n) {
$o = $n;
while(strpos($o,"_")) {
$o = preg_replace("/_/","+",$o,1);
$new[] = $o;
}
$o = strrev($n);
while(strpos($o,"_")) {
$o = preg_replace("/_/","+",$o,1);
$new[] = $o;
}
}
print_r($new);

Change the all the keys in a array in php

So I am playing around with arrays and I want to replace all of the keys in the array, so I have this array:
$array = array(1,5,8,0);
and this is how I replace the keys:
function recursive_change_key($arr, $set) {
if (is_array($arr) && is_array($set)) {
$newArr = array();
foreach ($arr as $k => $v) {
$key = array_key_exists( $k, $set) ? $set[$k] : $k;
$newArr[$key] = is_array($v) ? recursive_change_key($v, $set) : $v;
}
return $newArr;
}
return $arr;
}
$length = sizeof($array);
for($i = 0; $i < $length; $i++)
{
$people = recursive_change_key($array, array($i => "A"));
}
echo '<pre>';
print_r($people);
echo '</pre>';
So what I am trying to do is to replace all the array keys with A, but this is the result what I get:
And this is the result what I want:
(sorry for the bad editing)
I don't know what I am doing wrong. Could you please help?
The result you want is not possible to get. There cannot be several entries with the same key. For example, imagine you have general array $myArray, is it possible to have 3 $myArray[0] ? The answer is no and the same situation is with associative array.

php array sorting with next value difference

can anyone help me with this following Array sorting
Input
$array=array(1,2,3,6,7,8,100,101,200);
Output:
$new_array=array(
0=>array(1,2,3),
1=>array(6,7,8),
2=>array(100,101),
3=>array(200)
);
Thanks in advance!
$array=array(1,2,3,6,7,8,100,101,200);
$new_array = array();
$lastNumber = '';
foreach($array as $number) {
if($lastNumber === '') {
$otherArray = array($number);
}
elseif($lastNumber + 1 !== $number) {
$new_array[] = $otherArray;
$otherArray = array($number);
}
else{
$otherArray[] = $number;
}
$lastNumber = $number;
}
$new_array[] = $otherArray;
print_r($new_array);
You can loop over the array and check the distance to the next element in the array. If this distance is larger then one add a new sub array:
$array=array(1,2,3,6,7,8,100,101,200);
$result=array(array());
for($i=0; $i<count($array)-1; $i++)
{
if($array[$i+1]-$array[$i]==1)
{
// If difference to next number is one -> push
array_push($result[count($result)-1], $array[$i]);
}
else
{
// ... else: Push and create new array for the next element
array_push($result[count($result)-1], $array[$i]);
array_push($result, array());
}
}
// Push the last number
array_push($result[count($result)-1], $array[$i]);
print_r($result);
Just a different approach with array_push()...
Pretty simple: loop through the numbers, remember the last one, if the current number is not the successor of the last one, add a new array to your result, push into the last array in your result.
$result = [];
$last = null;
foreach ($array as $number) {
if ($last !== $number - 1) {
$result[] = [];
}
$result[count($result) - 1][] = $number;
$last = $number;
}
You could even get rid of $last and directly read the last array element of the last array element of $result, but that would make the code actually more complicated.

concatenate arrays with associative keys

I'll let the code speak:
$params = array();
$qtyCount = count(array(1,2,3,4,5));
$qtyAr = array(6,7,8,9,10);
$i = 1;
while($i <= $qtyCount){
$params['quantity_'.$i] .= $qtyAr[$i];
$i++;
}
But when I do this, the last value is missing.
BTW: the values in the qtyCount and qtyAr are bugus... just for example.
I would opt for a simpler approach:
array_walk($qtyAr, function($item, $index) use (&$params) {
$key = sprintf("quantity_%u", $index);
$params[$key] = $item;
});
It appears that you are starting at the wrong index (1), $i should be = 0 as others have pointed out.
You're missing the last element because your unasssociated array starts with 0 and your loop starts with 1. This is why foreach works so much better because it iterates over ALL your elements.
$qtyAr = array(6,7,8,9,10);
$i = 1;
foreach($qtyAr as $val) {
$params['quantity_' . $i] = $val;
$i++;
}

PHP: Transformation of array

There is the following array:
arr1 = array(array('xxx',3),array('yyy',2));
I need to transform it into the array arr2, where the number of occurrence of each entry is equal to the 2nd column value in array arr1. For instance, for the above given arr1, arr2 should be the following:
arr2 = array(array('xxx'),array('xxx'),array('xxx'),array('yyy'),array('yyy'));
I wrote the following code, but my question is: Is it possible to do the same in a simpler way?
for ($i=0; $i<count($arr1); $i++) {
for ($j=0; $j<$arr1[i][1]; $j++) {
$arr2[] = array($arr1[0]);
}
}
I think a foreach is simpler and easier to read.
$arr1 = array(array('xxx', 3), array('yyy', 2));
$arr2 = array();
foreach ($arr1 as $arr)
{
for ($i = 0; $i < $arr[1]; $i++)
{
$arr2[] = array($arr[0]);
}
}
foreach ($arr1 as $entry) {
$arr2[] = array_fill(0, $entry[1], array($entry[0]));
}
$arr2 = call_user_func_array('array_merge', $arr2);
I wouldn't use it though. It's much less readable.

Categories