How to remove duplicate letters in string in PHP - php

So I have this:
array(2) { [0]=> string(2) "cd" [1]=> string(6) "feegeg" }
And I have this code:
foreach ($elem as $key => $value) {
echo preg_replace('{(.)\1+}','$1',$value);
}
Which outputs:
cdfegeg
But I need it to output:
cdfeg
What do I need with preg_replace() or maybe not using preg_replace(), so I can get this output?

I tend to avoid regex when possible. Here, I'd just split all the letters into one big array and then use array_unique() to de-duplicate:
$unique = array_unique(str_split(implode('', $elem)));
That gives you an array of the unique characters, one character per array element. If you'd prefer those as a string, just implode the array:
$unique = implode('', array_unique(str_split(implode('', $elem))));

Multibyte character sets solution:
$buffer = [];
foreach (['cd', 'feegeg'] as $string)
{
$chars = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);
foreach ($chars as $index => $char)
{
if (isset($buffer[$char]))
{
unset($chars[$index]);
}
$buffer[$char] = true;
}
echo implode('', $chars);
}

Related

How to remove double quotes from array keys and values?

I have an array where both the keys and values are wrapped in double quotes. Is there a way to remove the double quotes?
var_dump($my_array);
array(2) {
[0]=>
array(1) {
[""Phone number""]=>
string(15) ""+1 555000555""
}
[1]=>
array(1) {
[""Phone number""]=>
string(15) ""+371 6665000559""
}
}
I tried looping through every element and removing the quotes but I'm getting error undefined variable $new_array
foreach($my_array as $key => $value) {
$new_array[] = str_replace('""', '', $key);
$new_array[] = str_replace('""', '', $value);
}
Although it would be better to fix the source of the data, your code was almost there. You should define any variables before you use them, and the way you do the replacements didn't add the item with the new key...
$new_array = [];
foreach($my_array as $key => $value) {
$new_array[str_replace('""', '', $key)] = str_replace('""', '', $value);
}
I'd use trim
$test = array (
0 =>
array (
"\"Phone number\"" => "\"+1 555000555\""
),
1 =>
array (
"\"Phone number\"" => "\"+371 6665000559\""
)
);
function trimQuotes(array $array){
$o = [];
foreach($array as $k=>$v){
if(is_array($v)){
$o[trim($k,"\"'")] = trimQuotes($v);
}else{
$o[trim($k,"\"'")] = trim($v,"\"'");
}
}
return $o;
}
var_dump(trimQuotes($test));
This will remove both " and ' that are leading and trailing, with no risk of removing other quotes in the string.
Output:
array(2) {
[0]=>
array(1) {
["Phone number"]=>
string(12) "+1 555000555"
}
[1]=>
array(1) {
["Phone number"]=>
string(15) "+371 6665000559"
}
}
Sandbox
The problem with a simple string replace method is that it will wipe all the quotes out in the string, regardless of where they are, that may or may not be an issue for you, though.

Convert PHP String to Associative Array

I have a string that looks like the below:
Name,Age,Location
Jo,28,London
How would I convert this into an associative array so it reads like this:
Array
(
[Name] => Jo
[Age] => 28
[Location] => London
)
I've tried to explode the string and manipulate it that way but got nowhere fast ($body = explode(',', $body);) I tried to use array_map() but it expected an array in the first place.
I've looked through a few articles (PHP CSV to Associative Array with Row Headings) but again they are using array_map().
You are trying to over-engineer simple thing, which result in wasting too much time for having task done.
$str = "Name,Age,Location\nJo,28,London";
$lines = explode("\n", $str);
$keys = explode(',', $lines[0]);
$vals = explode(',', $lines[1]);
$result = array_combine($keys, $vals);
But even ordinary loop would do the trick in your case and this is what you should end up with unless you had better ideas:
$result = [];
for($i=0; $i<count($keys); $i++) {
$result[$keys[$i]] = $vals[$i];
}
I also recommend getting thru list of available built-in array functions for future benefits.
This answer will handle multilined CSV files.
Array_shift will take the first line and make that the keys, then loop the rest of the lines and use the keys in array_combine.
$str = "Name,Age,Location
Jo,28,London
Do,35,London";
$arr= explode("\n", $str);
$keys = explode(",",array_shift($arr));
foreach($arr as $line){
$new[]= array_combine($keys, explode(",", $line));
}
var_dump($new);
https://3v4l.org/hAmCN
array(2) {
[0]=>
array(3) {
["Name"]=>
string(2) "Jo"
["Age"]=>
string(2) "28"
["Location"]=>
string(6) "London"
}
[1]=>
array(3) {
["Name"]=>
string(2) "Do"
["Age"]=>
string(2) "35"
["Location"]=>
string(6) "London"
}
}
you try this code:
$ex = explode(PHP_EOL, $string)
$arr = array_combine(explode(',',$ex[0]), explode(',',$ex[1]));
print_r($arr);die;
Try this, it's working:
$content = $string;
$delimiter = ",";
$enclosure = '"';
$escape = "\\" ;
$rows = array_filter(explode(PHP_EOL, $content));
$header = NULL;
$data = [];
foreach($rows as $row)
{
$row = str_getcsv ($row, $delimiter, $enclosure , $escape);
if(!$header) {
$header = $row;
} else {
$data[] = array_combine($header, $row);
}
}

How correctly to process an arrays?

There are two arrays:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
The number of elements in the second array is less than or equal to the first array.
Sort out the first array and the second array, if the elements of the second array are contained at the end of the elements of the first array, sort the array in this form:
Array
(
[0] => w_ord
[1] => tech
[2] => care
[3] => k_ek
[4] => l_ol
[5] => wi_ld
[6] => re_gex
)
Important: the elements of the second array are never repeated, and can go in any order. If in the second element there is no end of the element of the first array, then set the value of the element of the first array.
I do this:
foreach($arr2 as $val) {
$strrepl[$val] = "_".$val;
}
foreach($arr1 as $key => $val) {
$arr3[$key] = str_replace(array_keys($strrepl), $strrepl, $val);
}
print_r($arr3);
But I'm not sure that this is the right approach, what will you advise?
Hmm, let's see ... purely functional 'cause you know :D
function ends($str) {
return function($suffix) use($str) {
return mb_strlen($str) >= mb_strlen($suffix)
&& mb_substr($str, mb_strlen($suffix) * -1) === $suffix;
};
}
$result = array_map(function($item) use($arr2) {
$filter = ends($item);
$suffixes = array_filter($arr2, $filter);
if (empty($suffixes)) {
return $item;
}
// This only cares about the very first match, but
// is easily adaptable to handle all of them
$suffix = reset($suffixes);
return mb_substr($item, 0, mb_strlen($suffix) * -1) . "_{$suffix}";
}, $arr1);
Surprisingly, this one was quite fun to execute.
Since you went very specific on end of the element, I decided to use RegEx for that.
Here is my approach:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
foreach ($arr2 as $find) {
foreach ($arr1 as $key => $element) {
$arr1[$key] = preg_replace('/' . $find . '$/', '_' . $find, $element);
}
}
For every element of the second array (since they are not repeated), I go through every element of the first array and check if the value can be found at the end of the element of the second array using the $ anchor from RegEx which forces it to look it from the end of the string.
This way the $arr1 will have exactly what you expect.
[Edit]
Following the scape suggestion from #aefxx and improving variable names.
You can use preg_grep which is regex on arrays.
This code will also make sure it can output more than one matching word from $arr1.
$arr1 = ['word', 'chord', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
$keys=[];
foreach($arr2 as $val){
$matches = preg_grep("/.+" . preg_quote($val) . "/", $arr1);
$keys = array_merge($keys, array_keys($matches)); // save keys of matched words
foreach($matches as $key => $m) $new[$val][] = str_replace($val, "_$val", $arr1[$key]);
}
$new['unmatched'] = array_diff_key($arr1, array_flip($keys)); // add unmatched words
var_dump($new);
Output:
array(6) {
["ord"]=>
array(2) {
[0]=>
string(5) "w_ord"
[1]=>
string(6) "ch_ord"
}
["ek"]=>
array(1) {
[0]=>
string(4) "k_ek"
}
["ol"]=>
array(1) {
[0]=>
string(4) "l_ol"
}
["ld"]=>
array(1) {
[0]=>
string(5) "wi_ld"
}
["gex"]=>
array(1) {
[0]=>
string(6) "re_gex"
}
["unmatched"]=>
array(2) {
[2]=>
string(4) "tech"
[3]=>
string(4) "care"
}
}
https://3v4l.org/gfUea
You can try this.I think it is easy to understand :
$arr1=['word','tech','care','kek','lol','wild','regex'];
$arr2=['ord','ek','ol','ld','gex','ss'];
foreach($arr1 as $key=>$fullword){
foreach($arr2 as $substr){
$arr1[$key]=preg_replace('/' . $substr . '$/', '_' . $substr, $fullword,-1,$count);
if($count) break;
}
}
i go throught the array of fullword and as soon as i find a match i stop the search.
Another approach can be to create complex regex beforehand (using implode and preg_quote for safety) and use it for replacement inside array_map callback:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
$regex = '/(' . implode('|', array_map('preg_quote', $arr2)) . ')$/';
$result = array_map(function ($word) use ($regex) {
return preg_replace($regex, '_$1', $word);
}, $arr1);
Here is the demo.

how to take array with specific char?

i have array
Example :
array(3) { [0]=> string(6) "{what}" [1]=> string(5) "[why]" [2]=> string(5) "(how)" }
and then how to take array with specific char ("{") ?
Is my understanding here correct? You want to get items in array that has a "{" Character. Then why not just loop over it and check the item if it has that character and push it in a new array.
$array_with_sp_char = array();
foreach ($arr_items as $item) {
if (strpos($item, '{') !== FALSE) {
array_push($array_with_sp_char, $item);
}
}
Just iterate through your array and filter out the values you are interested in, in your case i guess it's the values that contain the Char "{"
A possible implementation:
$result = array_filter($your_array, function($value) {
return preg_match('/{/', $value);
});
Use a combination of array_filter and strpos:
$array = [
"{what}",
"[why]",
"(how)"
];
$array = array_filter($array, function($value) {
return strpos($value, '{') !== false;
});
print_r($array);
That will give you:
Array
(
[0] => {what}
)

How to delete elements from array from certain value on?

I have an array in PHP and I don't know how to delete all the elements from every array element from certain character on, icluding that character. Is there a way to do this?
array(1092) {
["Piper;Rosii;Sare;Test;Vinete#####Piper ->Negru;Rosii ->Călite;Sare ->De masă, grunjoasă;Vinete ->Prăjite"]=>
int(124)
}
In my example I want to delete all text from "#####", including "#####" to the end, foreach array element. Is this possible? Or is there a PHP function for this?
UPDATE
My result should look like this:
array(1092) {
["Piper;Rosii;Sare;Test;Vinete]=>
int(124)
}
You can use array_walk to apply the substr and strpos to each element:
$array = [
'23845637;54634;345;3453345;#####morestuff',
'234234#####34596078345j34534534',
'34343245dfg#####asdfsadf;23452345;sdfsdf;345345'
];
array_walk($array, function(&$value, $key) {
$value = substr($value, 0, strpos($value, '#####'));
});
var_dump($array);
Will result in:
array(3) {
[0]=>
string(27) "23845637;54634;345;3453345;"
[1]=>
string(6) "234234"
[2]=>
string(11) "34343245dfg"
}
This will modify the original array.
For each element in the array, we search for the position of '#####' in the string and only take the part from 0 to the position in the string where '#####' occurs.
This will do that by looping through the array exploding the key by ##### and adding it to a new array. I did it in a loop in case your array is bigger than 1
<?php
$oldArray = array("Piper;Rosii;Sare;Test;Vinete#####Piper ->Negru;Rosii ->Călite;Sare ->De masă, grunjoasă;Vinete ->Prăjite" => 124);
$newArray = array();
foreach ($oldArray as $key => $row) {
$newKey = explode('#####', $key);
$newArray[$newKey[0]] = $row;
}
var_dump($newArray);
You can use substr and strpos to add the new entry and then unset the old entry in the array like this example:
$array = array(
"Piper;Rosii;Sare;Test;Vinete#####Piper ->Negru;Rosii ->Călite;Sare ->De masă, grunjoasă;Vinete ->Prăjite" => 124
);
foreach ($array as $key => $value) {
$array[substr($key, 0, strpos($key, '#####'))] = $value;
unset($array[$key]);
}
var_dump($array);
Will result in:
array(1) {
["Piper;Rosii;Sare;Test;Vinete"]=>
int(124)
}

Categories