Search through array and removing duplicates - php

I am trying to remove duplicates from a text field. The text field auto suggests inputs and the user is only allowed to choose from them.
The user however has the option of choosing same input field more than once. It's an input fields that states the firstname + lastname of each individual from a database.
First, this is my code to trim some of the unwated characters and then going through the array comparing it to previous inputs.
if(!empty($_POST['textarea'])){
$text = $_POST['textarea'];
$text= ltrim ($text,'[');
$text= rtrim ($text,']');
$toReplace = ('"');
$replaceWith = ('');
$output = str_replace ($toReplace,$replaceWith,$text);
$noOfCommas = substr_count($output, ",");
echo $output.'<br>';
$tempArray = (explode(",",$output));
$finalArray[0] = $tempArray[0];
$i=0;
$j=0;
$foundMatch=0;
for ($i; $i<$noOfCommas; $i++) {
$maxJ = count($finalArray);
for ($j; $j<$maxJ; $j++) {
if ($tempArray[$i] === $finalArray[$j]) {
$foundMatch ===1;
}
}
if ($foundMatch === 0) {
array_push($finalArray[$j],$tempArray[$i]);
}
}
What is it am I doing wrong ?

In this part when checking if the values are equal:
if ($tempArray[$i] === $finalArray[$j]) {
$foundMatch ===1;
}
It should be:
if ($tempArray[$i] === $finalArray[$j]) {
$foundMatch = 1;
}
That way you are setting the variable and not checking if it's equal to 1. You can also break the inner for loop when finding the first match.

I think that this should work:
if (!empty($_POST['textarea'])){
$words = explode(',',str_replace('"', '', trim($_POST['textarea'], ' \t\n\r\0\x0B[]'));
array_walk($words, 'trim');
foreach ($words as $pos=>$word){
$temp = $words;
unset($temp[$pos]);
if (in_array($word, $temp))
unset($words[$pos]);
}
}
echo implode("\n", $words);
First it reads all the words from textarea, removes '"' and then trim. After that it creates a list of words(explode) followed by a trim for every word.
Then it checks every word from the list to see if it exists in that array (except for that pos). If it exists then it will remove it (unset).

Related

recursively get user input value in array values

I am leaning recursion and I want to create a search engine which depends on a user value and gets from an array all values which together make up the word that the user typed.
For example I have this array :
$array = array('it', 'pro', 'gram', 'grammer', 'mer', 'programmer');
$string = "itprogrammer";
If anyone can help I appreciate it a lot. Thank you for your help.
Here is a recursive function that will do what you want. It loops through the array, looking for words that match the beginning of the string. It it finds one, it then recursively tries to find words in the array (excluding the word already matched) which match the the string after it has had the first match removed.
function find_words($string, $array) {
// if the string is empty, we're done
if (strlen($string) == 0) return array();
$output = array();
for ($i = 0; $i < count($array); $i++) {
// does this word match the start of the string?
if (stripos($string, $array[$i]) === 0) {
$match_len = strlen($array[$i]);
$this_match = array($array[$i]);
// see if we can match the rest of the string with other words in the array
$rest_of_array = array_merge($i == 0 ? array() : array_slice($array, 0, $i), array_slice($array, $i+1));
if (count($matches = find_words(substr($string, $match_len), $rest_of_array))) {
// yes, found a match, return it
foreach ($matches as $match) {
$output[] = array_merge($this_match, $match);
}
}
else {
// was end of string or didn't match anything more, just return the current match
$output[] = $this_match;
}
}
}
// any matches? if so, return them, otherwise return false
return $output;
}
You can display the output in the format you desire with:
$wordstrings = array();
if (($words_array = find_words($string, $array)) !== false) {
foreach ($words_array as $words) {
$wordstrings[] = implode(', ', $words);
}
echo implode("<br>\n", $wordstrings);
}
else {
echo "No match found!";
}
I made a slightly more complex example (demo on rextester):
$array = array('pro', 'gram', 'merit', 'mer', 'program', 'it', 'programmer');
$strings = array("programmerit", "probdjsabdjsab", "programabdjsab");
Output:
string: 'programmerit' matches:
pro, gram, merit<br>
pro, gram, mer, it<br>
program, merit<br>
program, mer, it<br>
programmer, it
string: 'probdjsabdjsab' matches:
pro
string: 'programabdjsab' matches:
pro, gram<br>
program
Update
Updated code and demo based on OPs comments about not needing to match the whole string.

Change one of the array value if it equals to something

I'm using explode() php function to divide the sentence and turn it into array the user had filled in the input field on different page. From that sentence I need to find if there is that word and if it is in it add <b></b> around of that word. I've tried:
$wordsentence = explode(' ', $wordsentence);
$place == '0';
foreach ($wordsentence as $ws) {
if ($ws == $word) {
$word = '<b>'.$word.'</b>';
$save = $place;
}
$place++;
}
but there might be more than one word in the same sentence. Is there any way to mark multiple words?
You initial setup:
$wordSentence = "This is a sentence, made up of words";
$wordTest = "made";
$wordsArr = explode(' ', $wordSentence);
I swapped out the foreach loop for a standard for loop, this way we don't need to initialize a separate index variable and keep track of it.
for ($i = 0; $i < count($wordsArr); $i++) {
if ($wordsArr[$i] == $wordTest) {
$boldWord = '<b>' . $wordTest . '</b>';
//take your wordsArray, at the current index,
//swap out the old version with the bold version
array_splice($wordsArr, $i, 1, $boldWord);
}
}
And to complete our test:
$boldedSentence = implode(' ', $wordsArr);
echo $boldedSentence . "\n";
Output:
> This is a sentence, <b>made</b> up of words

How to display specific letters from a list of words in a loop?

I received this challenge in an interview and I would like some help solving it.
Using the input string: PHP CODING TECH, produce the following output.
PCT
PHCT
PHPCT
PHPCOT
PHPCODT
PHPCODIT
PHPCODINT
PHPCODINGT
PHPCODINGTE
PHPCODINGTEC
PHPCODINGTECH
As I understand it, the logic is to explode the input string on the spaces and then in a loop structure, display the leading letter(s) of each word as a single string. During each iteration (after the first), the earliest incomplete word displays an additional leading letter.
This is my coding attempt:
$str = "PHP CODING TECH";
$a = explode(' ', $str);
for ($i=0; $i < count($a); $i++) {
for ($j=0; $j < strlen($a[$i]) ; $j++) {
//echo "<pre>";
$b[$i][$j] = explode(' ', $a[$i][$j]);
}
}
echo "<pre>";
print_r($b);
Code: (Demo) (or with DO-WHILE())
$input = "PHP CODING TECH";
$counters = array_fill_keys(explode(' ', $input), 1); // ['PHP' => 1, 'CODING' => 1, 'TECH' => 1]
$bump = false; // permit outer loop to run
while (!$bump) { // while still letters to output....
$bump = true; // stop after this iteration unless more letters to output
foreach ($counters as $word => &$len) { // $len is mod-by-ref for incrementing
echo substr($word, 0, $len); // echo letters using $len
if ($bump && isset($word[$len])) { // if no $len has been incremented during inner loop...
++$len; // increment this word's $len
$bump = false; // permit outer loop to run again
}
}
echo "\n"; // separate outputs
}
Output:
PCT
PHCT
PHPCT
PHPCOT
PHPCODT
PHPCODIT
PHPCODINT
PHPCODINGT
PHPCODINGTE
PHPCODINGTEC
PHPCODINGTECH
Explanation:
I am generating an array of words and initial lengths from the exploded input string. $bump is dual-purpose; it not only controls the outer loop, it also dictates the word which gets a length increase within the inner loop. $len is "modifiable by reference" so that any given word's $len value can be incremented and stored for use in the next iteration. isset() is used on $word[$len] to determine if the current word has more available letters to output in the next iteration; if not, the next word gets a chance (until all words are fully displayed).
And while I was waiting for this page to be reopened, I whacked together an alternative method:
$input = "PHP CODING TECH";
$words = explode(' ', $input); // generates: ['PHP', 'CODING', 'TECH']
$master = ''; // initialize for first offset and then concatenation
foreach ($words as $word) {
$offsets[] = strlen($master); // after loop, $offsets = [0, 3, 9]
$master .= $word; // after loop, $master = 'PHPCODINGTECH'
}
$master_offsets = range(0, strlen($master)); // generates: [0,1,2,3,4,5,6,7,8,9,10,11,12]
do {
foreach ($offsets as $offset) {
echo $master[$offset];
}
echo "\n";
} while ($master_offsets !== ($offsets = array_intersect($master_offsets, array_merge($offsets, [current(array_diff($master_offsets, $offsets))])))); // add first different offset from $master_offsets to $offsets until they are identical

No Output? PHP foreach doesn't seem to work

I am trying to form an acronym from a given text. The Idea here is that the first Letter in $text ($text[0]) will be taken and placed inside the array $storage using array_push(). Now, if there is a space inside the array, the letter of the next index should be a part of the Acronym. I am currently not getting an ouput, what am I missing?
public function Acronym($text)
{
$text = str_split($text);
$count = strlen($text);
$storage = array();
for($i=0; $i<$count; $i++)
{
array_push($storage, $text[0]);
if($text[$i]==' ')
{
array_push($storage, $text[$i+1]);
}
foreach($storage as $clean)
{
echo $clean;
}
}
}
Your algorithm suffers from a few fatal flaws:
You're calling strlen() on an array, when you should be calling count():
$text = str_split($text);
$count = count($text);
However, you can index strings as arrays, so you don't need str_split() in this scenario, and you can keep $count = strlen( $text); by removing the call to str_split().
This should only happen once, so it should be outside the loop (This implies starting $i at 1):
array_push($storage, $text[0]);
Your foreach loop that prints the $storage array should be outside of the loop that is creating the acronym.
You can save the overhead of calling a function by using the shorthand array_push() notation. You should use array_push() when adding more than one element to an array. Otherwise, this will suffice:
$storage[] = $text[0];
You need to return something from your function, otherwise you won't be able to access anything outside of it.
Put that all together, and you get this:
public function Acronym($text)
{
$count = strlen( $text);
$storage[] = $text[0];
for( $i = 1; $i < $count; $i++)
{
if( $text[$i] == ' ')
{
$storage[] = $text[$i+1]);
$i++; // Can increment $i here because we know the next character isn't a space
}
}
foreach($storage as $clean)
{
echo $clean;
}
return $storage;
}
That being said, there are far better implementations for forming an acronym giving a string input. Here is one that I can think of:
public function Acronym( $text)
{
$acronym = array();
foreach( explode( ' ', $text) as $word)
{
$word = trim( $word);
$acronym[] = strtoupper( $word[0]);
}
return implode( '', $acronym);
}
Note that both functions will fail for inputs like Hello World. I am leaving it up to the OP to make these modifications (if necessary).
str_split turns the string into an array.
str_length brings the length of a string which you have overwritten with an array already. you need count()
You overwrite your first variable $text
$count = strlen($text);
In this line $text is an array, because you changed it in the first line of your method.
Try inverting the two first lines:
$count = strlen($text);
$text = str_split($text);
Note
This will solve your secondary problem, and enable your algorithm to run without errors. It doesn't fix your algorithm, but at least you will be able to debug it now.
you are running your loop on $count which is getting its value from str_len its an array because of return on $text = str_split($text);
So you have overwritten your $text variable you can fix it by changing order get length first then split.

Assign variable to values in array php

This is what I want to do:
Split a word into separate charachters. The input word comes from a form and can differ from each user.
Assign variables to each charachter so that i can manipulate them separately.
Her's my code so far (which doesn't work). Apoligize if ther's a lot of stupid mistakes here, but I am new to PHP.
<?php
$word = $_POST['input'];
//split word into charachters
$arr1 = str_split($word);
//assigning a variable to each charchter
$bokstaver = array();
while($row = $arr1)
{
$bokstaver[] = $row[];
}
$int_count = count($bokstaver);
$i=0;
foreach ($bokstaver as $tecken) {
$var = 'tecken' . ($i + 1);
$$var = $tecken;
$i++;
}
?>
I'd like to end up with as many $tecken variables (With the names $tecken, t$tecken1, $tecken2 etc) as the number of charachters in the input.
All help much appreciated, as always!
You don't need to create separate variables for each letter because you have all the letters in an array. Then you just index into the array to get out each letter.
Here is how I would do it.
//get the word from the form
$word = $_POST['input'];
//split word into characters
$characters = str_split($word);
//suppose the word is "jim"
//this prints out
// j
// i
// m
foreach($characters as $char)
print $char . "\n"
//now suppose you want to change the first letter so the word now reads "tim"
//Access the first element in the array (ie, the first letter) using this syntax
$characters[0] = "t";
I dont think its a good idea, but heres how you do it:
<?php
$input = 'Hello world!';
for($i = 0; $i < strlen($input); $i++) {
${'character' . $i} = $input[$i];
}
why do you want that?
you can just go with:
$word = 'test';
echo $word[2]; // returns 's'
echo $word{2}; // returns 's'
$word{2} = 'b';
echo $word{2}; //returns 'b'
echo $word; // returns 'tebt'
...

Categories