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.
Related
This question already has answers here:
Reverse the letters in each word of a string
(6 answers)
Closed 1 year ago.
This is the code I have so far. I just started learning PHP today and I'm not sure why my code isn't working.
<?php
function backwards($input)
{
$str = $input;
$revStr = "";
$str = explode(",",$str);
for($x = 0; $x < strlen($str); $x++){
$revStr .= strrev($str[$x]);
}
return $revStr;
}
Any help would be greatly appreciated!
edit: Here is an example input
Php,Arrays,Mysql
here is what i would like the output to be:
phP,syarrA,lqsyM
edit2:
Figured it out. Made a few minor edits. Not sure if it's the most efficient code but it works.
<?php
function backwards($input)
{
$str = $input;
$revStr = "";
$str = explode(",",$str);
for($x = 0; $x < count($str); $x++){
if($x == count($str) - 1){
$revStr .= strrev($str[$x]);
}
else{
$revStr .= strrev($str[$x]) . ",";
}
}
return $revStr;
}
Edit, I see you now included an example.
Use array_map and strrev to reverse the words.
Use explode and Implode to make the words array and back to string.
echo implode(",", array_map(function($part){ return strrev($part);},explode(",", $str)));
https://3v4l.org/tr7d6
I believe you should use array_reverse on the exploded string.
Then you can implode it back to a string.
$str = "apple,orange,tomato";
$arr = explode(",", $str);
$arr =array_reverse($arr);
echo implode(",", $arr); //tomato,orange,apple
https://3v4l.org/Hvd9m
Or, slightly messier but compact:
echo implode(",", array_reverse(explode(",", $str)));
https://3v4l.org/LTu90
You are checking the string length of an array inside of your for loop. Also, a custom function is unnecessary, PHP provides us with strrev().
But if you would like to use your own:
function backwards($input)
{
$str = $input;
$revStr = "";
$str = explode(",",$str);
for($x = 0; $x < count($str); $x++){
$revStr .= strrev($str[$x]);
}
return $revStr;
}
$string = "Php,Arrays,Mysql";
echo backwards($string);
Hope this helps,
You need to use count instead of strlen and also need to take reversed string into array and then convert it into string.
You can try this code :
<?php
function backwards($input)
{
$str = $input;
$revStr = array();
$str = explode(",", $str);
for ($x = 0; $x < count($str); $x++) {
$revStr[] = strrev($str[$x]);
}
return implode(',', $revStr);
}
$str = "Php,Arrays,Mysql";
var_dump(backwards($str));
Just some modification and you got your desired output. You can use explode and implode function of php with array_push to get your result:
<?php
$string = "Php,Arrays,Mysql";
function backwards($input)
{
$str = $input;
$revStr = array();
$str = explode(",", $str);
for ($x = 0; $x < count($str); $x++) {
array_push($revStr, strrev($str[$x]));
}
return implode(',', $revStr);
}
$result =backwards($string);
echo $result;
?>
You can check the demo here
use $str[0] in for loop syntax.
like this => for($x = 0; $x < strlen($str[0]); $x++)
I'm trying to parse a string and delete the adjacent letters that are same. I want to return the count of number of deletions and output the resulted string after the deletions are made. Say I have
$str = "aaabbbcc";
As you can see, you need to do 5 deletions to make the adjacent letters not same. The $output string is "abc" and the number of deletions is five.
function str_deletions ($str)
{
$prev = $str[0];
$length = strlen($str);
$deletions = 0;
$output = "";
for ($i=1 ; $i < $length; $i++)
{
if ($str[$i]== $prev)
{
$deletions++;
$prev = $str[$i]; // not sure here ?
}
}
echo $output; // ?
return $deletions;
}
$str = "aabbcc";
echo str_deletions ($str);
EDIT
This is an interview question, I'm not supposed to use any built-in functions like regex or array_count_values
Thanks for your help !
Here is another regex solution. I use a regex to only match a word character that is repeated, and then remove each consecutive repeating character one by one, which allows me to use &$count argument with preg_replace:
count
If specified, this variable will be filled with the number of replacements done.
The regex is
(\w)(?=\1)
See demo. Note you can replace \w with . to match any character but a newline. OR if you need to match only letters, I suggest using '/(\p{L})(?=\1)/u'
See IDEONE demo:
$str = "aaabbbcc";
$cnt = -1;
$result = preg_replace('/(\w)(?=\1)/', "", $str, -1, $cnt);
echo "Result: " . $result . PHP_EOL . "Deletions: " . $cnt;
Output:
Result: abc
Deletions: 5
Regex solution
This is a much simpler way of doing what you're after using preg_replace():
<?php
function str_deletions($str){
$replaced = preg_replace("/(.)\\1+/", "", $str);
$length = strlen($str) - strlen($replaced);
return array("new_word" => $replaced, "chars_replaced" => $length);
}
$str = "aabbcc";
$string_deletions = str_deletions($str);
echo "New String: " . $string_deletions['new_word'] . "\n";
echo "Chars deleted: " . $string_deletions['chars_replaced'] . "\n";
?>
No inbuilt functions
For the purposes of completion (and since you updated your question with more information to say that we can't use regexes because it's an interview question), here's what I'd do:
Using count_chars():
function str_deletions($str){
$string_data['new_word'] = count_chars($str,3);
$string_data['chars_replaced'] = strlen($str) - strlen($string_data['new_word']);
return $string_data;
}
$str = "aabbcc";
echo str_deletions($str);
Note: in this example count_chars(); will return unique chars in a string, not quite remove duplicates (i.e. "aabbccaa" would still yield "abc" as an output) but your question wasn't clear what the interviewer wanted - whether it was truly a remove duplicate question or a unique char question.
Using array_unique():
Slightly slower and a bit more heavy handed:
function str_deletions($str){
$string_array = array_unique(str_split($str));
foreach($string_array as $string_cur){
$string_data['new_word'] .= $string_cur;
}
$string_data['chars_replaced'] = strlen($str) - strlen($string_data['new_word']);
return $string_data;
}
$str = "aabbcc";
echo str_deletions($str);
Note: It's worth pointing out that if I realised it was an interview question, I wouldn't have provided an answer as doing it for you kind of defeats the purpose. Still, with the amount of answers here now and the fact that I've seen something similar to this in an interview, my hope is someone will learn from these.
The basic algorithm (indeed $prev = $str[$i]; isn't at the good place but you wasn't far):
function str_deletion($str) {
$del = 0;
if (1 < $length = strlen($str)) { // $str has more than 1 char
$prev = $str[0];
$output = $prev;
for ($i=1; $i<$length; $i++) {
if ($prev == $str[$i]) {
$del++;
} else {
$prev = $str[$i]; // when different, change the previous character
$output .= $prev; // and append it to the output
}
}
} else {
$output = $str;
}
echo $output;
return $del;
}
I have changed your function
this is not returning both the output string and number of deletions
function str_deletions ($str)
{
$prev = NULL;
$deletions = 0;
$output = "";
$i=0;
while ($i < strlen($str))
{
if (substr($str,$i,1) == $prev)
{
$deletions++;
//$prev = substr($str,$i,1);/*remove this line, no need here as the same stmnt is there after ifelse*/
}else{
$output.=substr($str,$i,1);
}
$prev = substr($str,$i,1);
$i++;
}
$arr = array(
'output'=>$output,
'deletions'=>$deletions
);
return $arr;
}
$str = "aaabbcc";
print_r(str_deletions ($str));
output for above function call is
Array ( [output] => abc [deletions] => 4 )
Solved with no external function except count;
$str="aaavvvffccca";
$count = strlen($str);
for($i=0;$i<$count;$i++){
$array[]=$str[$i];
}
$del =0;
for($i=0;$i<$count;$i++){
$next=isset($array[$i+1])?$array[$i+1]:null;
if($array[$i]==$next)
{
$del++;
}
else
{
$newarray[]=$array[$i];
}
}
echo "Filter Text:". implode('',$newarray);
echo"Total Deleted:".$del;
The straight forward solution to find out the number of deletions can be
If there are N consecutive same characters delete N-1 out of those N characters.
function str_likes($str)
{
$length = strlen($str);
$del = 0;
for ($i=0 ; $i < $length ; $i++)
{
if ($str[$i] == $str[$i+1])
{
$del++;
}
}
return $del;
}
$str = "aabbccaaa";
echo str_likes($str); //4
I have a string e.g. 1398723242. I am trying to check this string and get the odd numbers out which in this case is 13973.
I am facing problem on how to put this string into an array. After putting the string into an array I know that I have to loop through the array, something like this:
foreach($array as $value){
if($value % 2 !== 0){
echo $value;
}
}
So can any body please help on the first part on "How to put the above string into an array so I can evaluate each digit in the above loop?"
This should work for you:
Just use str_split() to split your string into an array. Then you can use array_filter() to filter the even numbers out. e.g.
<?php
$str = "1398723242";
$filtered = array_filter(str_split($str), function($v){
return $v & 1;
});
echo implode("", $filtered);
?>
output:
13973
Array map is your function (mixed with split)
$array = array_map('intval', str_split($number));
foreach($array as $value){
if($value % 2 !== 0){
echo $value;
}
}
Use str_split() http://www.php.net/manual/en/function.str-split.php
$string = "1398723242";
$array = str_split($string);
foreach($array as $value){
if($value % 2 !== 0){
echo $value;
}
}
if you want string as result, don't convert to array
$str = "1398723242";
echo preg_replace('/0|2|4|6|8/','', $str); //13973
Or, more faster
echo str_replace(array(0,2,4,6,8),'', $str); //13973
You have to know if the string is an array of chars. so you can just iterate it :
<?php
$string = "1398723242";
for($i=0; $i < strlen($string); ++$i){
if($string[$i]=='....'){
$string[$i] = ''; // Just replace the index like this
}
}
?>
$str = '1398723242';
$strlen = strlen($str);// Get length of thr string
$newstr;
for($i=0;$i<$strlen;$i++){ // apply loop to get individual character
if($str[$i]%2==1){ // check for odd numbers and get into a string
$newstr .= $str[$i];
}
}
echo $newstr;
I have to determine the position of a special character in the string for example:
E77eF/74/VA on 6 and 9 position (counting from 1)
we have '/' so I have to change them to position number -> E77eF6749VA
On MSSQL I could use PATINDEX but I need to use php for this.
It should work for everything except 0-9a-zA-Z
I found strpos() and strrpos() on php.net but I doens't work well for me.
Anyway tries to do something like that?
<?php
$content = 'E77eF/74/VA';
//With this pattern you found everything except 0-9a-zA-Z
$pattern = "/[_a-z0-9-]/i";
$new_content = '';
for($i = 0; $i < strlen($content); $i++) {
//if you found the 'special character' then replace with the position
if(!preg_match($pattern, $content[$i])) {
$new_content .= $i + 1;
} else {
//if there is no 'special character' then use the character
$new_content .= $content[$i];
}
}
print_r($new_content);
?>
Output:
E77eF6749VA
Might not be the most efficient way, but works.
$string = 'E77eF/74/VA';
$array = str_split($string);
foreach($array as $key => $letter){
if($letter == '/'){
$new_string.= $key+1;
}
else{
$new_string.= $letter;
}
}
echo $new_string; // prints E77eF6749VA
I'm using an RTF converter and I need 240 as &#U050&#U052&#U048 but Im not to sure how to do this!?!
I have tried using the following function:
function string_to_ascii($string) {
$ascii = NULL;
for ($i = 0; $i < strlen($string); $i++) {
$ascii += "&#U"+str_pad(ord($string[$i]),3,"0",STR_PAD_LEFT);
}
return($ascii);
}
But it still just outputs just the number (e.g. 2 = 50) and ord just makes it go mad.
I've tried echo "-&#U"+ord("2")+"-"; and I get 50416 !?!?
I have a feeling it might have something to do with encoding
I think you're over thinking this. Convert the string to an array with str_split, map ord to all of it, then if you want to format each one, use sprintf (or str_pad if you'd like), like this:
function string_to_ascii($string) {
$array = array_map( 'ord', str_split( $string));
// Optional formatting:
foreach( $array as $k => &$v) {
$v = sprintf( "%03d", $v);
}
return "&#U" . implode( "&#U", $array);
}
Now, when you pass string_to_ascii( '240'), you get back string(18) "&#U050&#U052&#U048".
Just found this:
function to_ascii($string) {
$ascii_string = '';
foreach (str_split($string) as $char) {
$ascii_string .= '&#' . ord($char) . ';';
}
return $ascii_string;
}
here