How to count and print characters that occur at least Y times? - php

I want to count the number of occurrences of each character in a string and print the ones that occur at least Y times.
Example :
Examples func(X: string, Y: int):
func("UserGems",2) => ["s" => 2, "e" => 2]
func("UserGems",3) => []
This what I could achieve so far:
$str = "PHP is pretty fun!!";
$strArray = count_chars($str, 1);
$num = 1;
foreach ($strArray as $key => $value) {
if ($value = $num) {
echo "The character <b>'".chr($key)."'</b> was found $value time(s)
<br>";
}
}

Firstly, you need to list all letters count with separately and to calculate it. Also, you need to calculate elements equal to count which is your find. I wrote 3 types it for your:
<?php
function check($string,$count) {
$achives = [];
$strings = [];
$strArray = count_chars($string, 1);
if($count) {
foreach($strArray as $char => $cnt) {
if($cnt==$count) {
$achives[chr($char)] = $cnt;
}
}
}
return $achives;
}
echo '<pre>';
print_r(check("aa we are all theere Tural a1",1));
So, it is very short version
function check($string,$count = 1) {
$achives = [];
$strArray = count_chars($string, 1);
array_walk($strArray,function($cnt,$letter) use (&$achives,$count){
$cnt!==$count?:$achives[chr($letter)] = $cnt;
});
return $achives;
}
echo '<pre>';
print_r(check("aa we are all theere Tural a1",3));
But it is exactly answer for your question:
<?php
function check($string,$count) {
$achives = [];
$strings = [];
$strArray = str_split($string, 1);
foreach($strArray as $index => $char ){
$strings[$char] = isset($strings[$char])?++$strings[$char]:1;
}
if($count) {
foreach($strings as $char => $cnt) {
if($cnt==$count) {
$achives[$char] = $cnt;
}
}
}
return $achives;
}
<?php
function check($string,$count) {
$achives = [];
$strings = [];
$strArray = count_chars($string, 1);
if($count) {
foreach($strArray as $char => $cnt) {
if($cnt==$count) {
$achives[chr($char)] = $cnt;
}
}
}
return $achives;
}
echo '<pre>';
print_r(check("aa we are all theere Tural a1",1));

You can simply do this with php str_split() and array_count_values() built in functions. i.e.
$chars = str_split("Hello, World!");
$letterCountArray = array_count_values($chars);
foreach ($letterCountArray as $key => $value) {
echo "The character <b>'".$key."'</b> was found $value time(s)\n";
}
Output

Related

Change case of every nth letter in a string in PHP

Locked. There are disputes about this question’s content being resolved at this time. It is not currently accepting new answers or interactions.
I am trying to write a simple program which takes every 4th letter (not character) in a string (not counting spaces) and changes the case to it's opposite (If it's in lower, change it to upper or vice versa).
What I have so far:
echo preg_replace_callback('/.{5}/', function ($matches){
return ucfirst($matches[0]);
}, $strInput);
Expected Result: "The sky is blue" should output "The Sky iS bluE"
$str = 'The sky is blue';
$strArrWithSpace = str_split ($str);
$strWithoutSpace = str_replace(" ", "", $str);
$strArrWithoutSpace = str_split ($strWithoutSpace);
$updatedStringWithoutSpace = '';
$blankPositions = array();
$j = 0;
foreach ($strArrWithSpace as $key => $char) {
if (empty(trim($char))) {
$blankPositions[] = $key - $j;
$j++;
}
}
foreach ($strArrWithoutSpace as $key => $char) {
if (($key +1) % 4 === 0) {
$updatedStringWithoutSpace .= strtoupper($char);
} else {
$updatedStringWithoutSpace .= $char;
}
}
$arrWithoutSpace = str_split($updatedStringWithoutSpace);
$finalString = '';
foreach ($arrWithoutSpace as $key => $char) {
if (in_array($key, $blankPositions)) {
$finalString .= ' ' . $char;
} else {
$finalString .= $char;
}
}
echo $finalString;
Try this:
$newStr = '';
foreach(str_split($str) as $index => $char) {
$newStr .= ($index % 2) ? strtolower($char) : strtoupper($char);
}
it capitalize every 2nd character of string
<?php
$str = "The sky is blue";
$str = str_split($str);
$nth = 4; // the nth letter you want to replace
$cnt = 0;
for ($i = 0; $i < count($str); $i++) {
if($str[$i]!=" " && $cnt!=$nth)
$cnt++;
if($cnt==$nth)
{
$cnt=0;
$str[$i] = ctype_upper($str[$i])?strtolower($str[$i]):strtoupper($str[$i]);
}
}
echo implode($str);
?>
This code satisfies all of your conditions.
Edit:
I would have used
$str = str_replace(" ","",$str);
to ignore the whitespaces in the string. But as you want them in the output as it is, so had to apply the above logic.

Comma separated string to parent child relationship array php

I have a comma separated string like
$str = "word1,word2,word3";
And i want to make a parent child relationship array from it.
Here is an example:
Try this simply making own function as
$str = "word1,word2,word3";
$res = [];
function makeNested($arr) {
if(count($arr)<2)
return $arr;
$key = array_shift($arr);
return array($key => makeNested($arr));
}
print_r(makeNested(explode(',', $str)));
Demo
function tooLazyToCode($string)
{
$structure = null;
foreach (array_reverse(explode(',', $string)) as $part) {
$structure = ($structure == null) ? $part : array($part => $structure);
}
return $structure;
}
Please check below code it will take half of the time of the above answers:
<?php
$str = "sports,cricket,football,hockey,tennis";
$arr = explode(',', $str);
$result = array();
$arr_len = count($arr) - 1;
$prev = $arr_len;
for($i = $arr_len; $i>=0;$i--){
if($prev != $i){
$result = array($arr[$i] => $result);
} else {
$result = array ($arr[$i]);
}
$prev = $i;
}
echo '<pre>',print_r($result),'</pre>';
Here is another code for you, it will give you result as you have asked :
<?php
$str = "sports,cricket,football,hockey,tennis";
$arr = explode(',', $str);
$result = array();
$arr_len = count($arr) - 1;
$prev = $arr_len;
for($i = $arr_len; $i>=0;$i--){
if($prev != $i){
if($i == 0){
$result = array($arr[$i] => $result);
}else{
$result = array(array($arr[$i] => $result));
}
} else {
$result = array ($arr[$i]);
}
$prev = $i;
}
echo '<pre>',print_r($result),'</pre>';

Key exist in complexe array

I would like to test if the key of an associative array exist in my $_POST.
my $_POST is like that:
$_POST["balle"]["x"] = 5;
$_POST["balle"]["y"] = 5;
$_POST["balle"]["z"] = 5;
or like that by example:
$_POST["p1"][1]["vit"] = 7;
$_POST["p1"][1]["angle"] = 32;
$_POST["p2"][2]["vit"] = 17;
$_POST["p2"][2]["angle"] = 2;
the values don't matter but I must check how are my $_POST keys.
I don't understand how i can test recursivly that because the $_POST can change and have differents forms.
I have try this:
function Check_post($new, $arr)
{
echo "Init<br/>";
$res = true;
if (is_array($new))
{
foreach ($new as $key => $value)
{
if (!in_array($key, $arr))
{
echo "Fail $key";
print_r($arr);
return (false);
}
$res = $res & Check_post($new[$key], $arr[$key]);
}
}
else
$res = in_array($new, $arr);
echo "MY RESULT";
var_dump($res);
return ($res);
}
$b = array();
$b["balle"] = array("x", "y", "z");
$post = array();
$post["balle"] = array();
$post["balle"]["x"] = 50;
$post["balle"]["y"] = 50;
$post["balle"]["z"] = 50;
echo "<pre>";
print_r($b);
echo "</pre><pre>";
print_r($post);
echo "</pre>";
Check_post($b, $post);
but i got "Fail balle". my $post variable is to simulate the real $_POST and for make it easier to test.
EDIT:
The function should work like that:
1) test if "balle" exist in $post
2) "balle" exist so recursive call
3) test if "x" exist in $post["balle"](recursive)
4) test if "y" exist in $post["balle"](recursive)
5) test if "z" exist in $post["balle"](recursive)
6) all existe so $res = true
EDIT:
I finaly editet the whole function:
function Check_post($needle, $haystack)
{
if(is_array($needle)){
foreach ($needle as $key => $element){
$result = true;
if($result = (array_key_exists($key, $haystack) || array_key_exists($element, $haystack))){
$key = (isset($haystack[$key]) ? $key : $element);
if(is_array($haystack[$key]))
$result = Check_post($element, $haystack[$key]);
}
if(!$result){
return false;
}
}
return $result;
}else {
return array_key_exists($needle, $haystack);
}
}
Now it should work as you want it
Example:
$_POST["balle"]["x"] = 5;
$_POST["balle"]["y"] = 5;
$_POST["balle"]["z"] = 5;
$b = array();
$b["balle"] = array("x", "y", "z");
var_dump(Check_post($b, $_POST)); //returns true
$b["balle"] = array("x", "y", "z", "b");
var_dump(Check_post($b, $_POST)); //returns false
The in_array function you're using checks if $key is contained in $arr as a value. If I got you right, you want to check if there is the same key in $arr instead. Use array_key_exists($key, $arr) for this.
Try this
$_POST["p1"][1]["vit"] = 7;
$_POST["p1"][1]["angle"] = 32;
$_POST["p2"][2]["vit"] = 17;
$_POST["p2"][2]["angle"] = 2;
$needle = "2";
$samp = Check_post($_POST,$needle);
echo $samp;
function Check_post($array,$needle)
{
if(is_array($array))
{
foreach($array as $key=>$value)
{
if($key == $needle)
{
echo $key." key exists ";
}
else
{
if(is_array($value))
{
check_post($value,$needle);
}
}
}
}
}
Demo

Output in an A-Z and non A-Z characters in a List

I am trying to output any array to a directory list format.
A-Z is working, but I want to output words that don't begin with A-Z to the symbol #.
E.G. 1234, #qwerty, !qwerty, etc should be sorted to the # group.
<?php
$aTest = array('apple', 'pineapple', 'banana', 'kiwi', 'pear', 'strawberry', '1234', '#qwerty', '!qwerty');
$range = range('A','Z');
$range[] = "#";
$output = array();
foreach($range AS $letters){
foreach($aTest AS $fruit){
if(ucfirst($fruit[0]) == $letters){
$output[$letters][] = ucfirst($fruit);
}
}
}
foreach($output AS $letter => $fruits){
echo $letter . "<br/>--------<br/>\n";
sort($fruits);
foreach($fruits AS $indFruit){
echo $indFruit . "<br/>\n";
}
echo "<br/>\n";
}
?>
$output['#'] = array();
foreach($range as $letter){
$output[$letter] = array();
}
foreach($aTest AS $fruit){
$uc = ucfirst($fruit);
if(array_search($uc[0], $range) === FALSE){
$output['#'][] = $uc;
} else {
$output[$uc[0]][] = $uc;
}
}
notice that I have removed outer loop, as you don't need it
You should reverse the order of the two foreach loops, use break and a temporary variable:
foreach($aTest as $fruit){
$temp = 1;
foreach($range as $letters){
if(ucfirst($fruit[0]) == $letters){
$output[$letters][] = ucfirst($fruit);
$temp = 0;
break;
}
}
if($temp){
$output["#"][] = $fruit;
}
}
ksort($output);
To avoid these complications, you may use only one foreach loop and the built-in PHP function in_array:
foreach($aTest as $fruit){
$first = ucfirst($fruit[0]);
if(in_array($first, $range)){
$output[$first][] = ucfirst($fruit);
}
else{
$output["#"][] = $fruit;
}
}
ksort($output);
I would categorize them first using ctype_alpha() and then sorting the result by the array key:
$output = array();
foreach ($aTest as $word) {
$output[ctype_alpha($word[0]) ? strtoupper($word[0]) : '#'][] = $word;
}
ksort($output);

Multiple String Replace Based on Index

I need to replace multiple sections of a string based on their indices.
$string = '01234567890123456789';
$replacements = array(
array(3, 2, 'test'),
array(8, 2, 'haha')
);
$expected_result = '012test567haha0123456789';
Indices in $replacements are expected not to have overlaps.
I have been trying to write my own solution, split the original array into multiple pieces based on sections which needs to be replaced or not, and finally combine them:
echo str_replace_with_indices($string, $replacements);
// outputs the expected result '012test567haha0123456789'
function str_replace_with_indices ($string, $replacements) {
$string_chars = str_split($string);
$string_sections = array();
$replacing = false;
$section = 0;
foreach($string_chars as $char_idx => $char) {
if ($replacing != (($r_idx = replacing($replacements, $char_idx)) !== false)) {
$replacing = !$replacing;
$section++;
}
$string_sections[$section] = $string_sections[$section] ? $string_sections[$section] : array();
$string_sections[$section]['original'] .= $char;
if ($replacing) $string_sections[$section]['new'] = $replacements[$r_idx][2];
}
$string_result = '';
foreach($string_sections as $s) {
$string_result .= ($s['new']) ? $s['new'] : $s['original'];
}
return $string_result;
}
function replacing($replacements, $idx) {
foreach($replacements as $r_idx => $r) {
if ($idx >= $r[0] && $idx < $r[0]+$r[1]) {
return $r_idx;
}
}
return false;
}
Is there any more effective way to achieve the same result?
The above solution doesn't look elegant and feels quite long for string replacement.
Use this
$str = '01234567890123456789';
$rep = array(array(3,3,'test'), array(8,2,'haha'));
$index = 0;
$ctr = 0;
$index_strlen = 0;
foreach($rep as $s)
{
$index = $s[0]+$index_strlen;
$str = substr_replace($str, $s[2], $index, $s[1]);
$index_strlen += strlen($s[2]) - $s[1];
}
echo $str;

Categories