remove all duplicates words from a given sentence in JavaScript - javascript

Take the following string as an example:
var string = "All is well if it ends well";
From this string I would like to find the duplicate words, remove all the duplicates keeping one occurrence of the word in place and then output the revised string and also Reverse.
Which in this example would be:
var string = "ends it if is All"

I would turn the string to an array, then remove duplicate, and then I would re-build the string.
Like so :
const string = 'All is well if it ends well';
const strToArr = string.split(' ');
const uniqueElementArr = Array.from(new Set(strToArr));
const newStr = uniqueElementArr.toString().replaceAll(',', ' ');
console.log(newStr) // outputs 'All is well if it ends'
I guess one could make it shorter

Related

JavaScript get first name and last name from string as array

I have a string that has the following format: <strong>FirstName LastName</strong>
How can I change this into an array with the first element firstName and second lastName?
I did this, but no luck, it won't produce the right result:
var data = [myString.split('<strong>')[1], myString.split('<strong>')[2]]
How can I produce ["firstName", "lastName"] for any string with that format?
In order to parse HTML, use the best HTML parser out there, the DOM itself!
// create a random element, it doesn't have to be 'strong' (e.g., it could be 'div')
var parser = document.createElement('strong');
// set the innerHTML to your string
parser.innerHTML = "<strong>FirstName LastName</strong>";
// get the text inside the element ("FirstName LastName")
var fullName = parser.textContent;
// split it into an array, separated by the space in between FirstName and LastName
var data = fullName.split(" ");
// voila!
console.log(data);
EDIT
As #RobG pointed out, you could also explicitly use a DOM parser rather than that of an element:
var parser = new DOMParser();
var doc = parser.parseFromString("<strong>FirstName LastName</strong>", "text/html");
console.log(doc.body.textContent.split(" "));
However, both methods work perfectly fine; it all comes down to preference.
Just match everything between <strong> and </strong>.
var matches = "<strong>FirstName LastName</strong>".match(/<strong>(.*)<\/strong>/);
console.log(matches[1].split(' '));
The preferred approach would be to use DOM methods; create an element and get the .textContent then match one or more word characters or split space character.
let str = '<strong>FirstName LastName</strong>';
let [,first, last] = str.split(/<[/\w\s-]+>|\s/g);
console.log(first, last);
/<[/\w\s-]+>|\s/g
Splits < followed by one or more word, space or dash characters characters followed by > character or space to match space between words in the string.
Comma operator , within destructuring assignment is used to omit that index from the result of .split() ["", "FirstName", "LastName", ""].
this is my approach of doing your problem. Hope it helps!
var str = "<strong>FirstName LastName</strong>";
var result = str.slice(0, -9).substr(8).split(" ");
Edit: it will only work for this specific example.
Another way to do this in case you had something other than an html
var string = "<strong>FirstName LastName</strong>";
string = string.slice(0, -9); // remove last 9 chars
string = string.substr(8); // remove first 8 chars
string = string.split(" "); // split into an array at space
console.log(string);

How can I split commas and periods from words inside of string using split?

I am trying to change specific word in a string with something else. For example, I want to change 'John' in let name = 'Hi, my name is John.'; to 'Jack'.
I know how to split a string by words or characters. I also know how to remove commas, periods, and other symbols in a string. However, if I split the given string with a separator (" "), I will have 'John.' which I do not want. (I know I can switch 'John.' with 'Jack.' but assume that I have an key and value pairs in an object and I am using the values which are names {Father: Jack, Mother: Susan, ...}
I don't know how to separate a string word by word including commas and periods.
For example, if I was given an input which is a string:
'Hi, my name is John.'
I want to split the input as below:
['Hi', ',', 'my', 'name', 'is', 'John', '.']
Does anyone know how to do it?
Below is the challenge I am working on.
Create a function censor that accepts no arguments. censor will return a function that will accept either two strings, or one string. When two strings are given, the returned function will hold onto the two strings as a pair, for future use. When one string is given, the returned function will return the same string, except all instances of a first string (of a saved pair) will be replaced with the second string (of a saved pair).
//Your code here
const changeScene = censor();
changeScene('dogs', 'cats');
changeScene('quick', 'slow');
console.log(changeScene('The quick, brown fox jumps over the lazy dogs.')); // should log: 'The slow, brown fox jumps over the lazy cats.'
I think your real question is "How do I replace a substring with another string?"
Checkout the replace method:
let inputString = "Hi, my name is John.";
let switch1 = ["John", "Jack"];
let switched = inputString.replace(switch1[0], switch1[1]);
console.log(switched); // Hi, my name is Jack.
UPDATE: If you want to get ALL occurrences (g), be case insensitive (i), and use boundaries so that it isn't a word within another word (\\b), you can use RegExp:
let inputString = "I'm John, or johnny, but I prefer john.";
let switch1 = ["John", "Jack"];
let re = new RegExp(`\\b${switch1[0]}\\b`, 'gi');
console.log(inputString.replace(re, switch1[1])); // I'm Jack, or johnny, but I prefer Jack.
You can Try This ...
var string = 'Hi, my name is John.';
//var arr = string.split(/,|\.| /);
var arr = string.split(/([,.\s])/);
console.log(arr);
Using 'Hi, my name is John.'.split(/[,. ]/); will do the job. It will split commas and periods and spaces.
Edit: For those who want to keep the comma and period, here is my wildly inefficient method.
var str = 'Hi, my name is John.'
str = str.replace('.', 'period');
str = str.replace(',', 'comma');
str = str.split(/[,. ]/);
for (var i = 0; i < str.length; i++) {
if (str[i].indexOf('period') > -1) {
str[i] = str[i].replace('period', '');
str.splice(i+1, 0, ".");
} else if (str[i].indexOf('comma') > -1) {
str[i] = str[i].replace('comma', '');
str.splice(i+1, 0, ",");
}
}
console.log(str);

Apply array of string with string.replace

Let's say I have a string like so:
const sentence = "This is my custom string";
I want to highlight the words of a input field inside this sentence.
Let's say a say user typed a string and I have converted the separate words into an array like so:
["custom", "string", "is"]
I know want to replace the words in my sentence with a highlighted version of the words in my array. For a single word I would do something like this:
const word = 'custom';
const searchFor = new RegExp(`(${word})`, 'gi');
const replaceWith = '<strong class="highlight">$1</strong>';
const highlightedSentence = sentence.replace(searchFor, replaceWith);
How can I apply this logic with an array to the entire sentence?
I can't simply loop through it because the string will contain my highlighted class which will also be taken into the highlighting process the the second loop, third loop, etc.
This means that on a second loop if a user where to type:
"high custom"
I would highlight my highlighted class, leading to highlight inception.
For an example of what I mean try commenting/uncommenting the 2 highlighter functions:
https://jsfiddle.net/qh9ttvp2/1/
Your problem is that while replacing words, you replace already added html tag with .class 'highlight'.
Solution here could be to replace anything that is not html tag. Replace this line in you jsfiddle example.
const searchFor = new RegExp(`(${word})(?!([^<]+)?>)`, 'gi');
You can split you sentence into array and check if your element is already highlighted:
let sentence = "This is a some type of long string with all kinds of words in it, all kinds.";
let sentenceArr = sentence.split(' '); // make an array
const query = "kinds words all type";
function highlighter(query, sentence) {
const words = query.match(/\S+/g);
words.forEach((word) => {
// Create a capture group since we are searching case insensitive.
const searchFor = new RegExp(`(${word})`, 'gi');
const replaceWith = '<strong class="highlight">$1</strong>';
sentenceArr = sentenceArr.map(sw => (sw.indexOf('strong class="highlight"') === -1) ? sw.replace(searchFor, replaceWith) : sw); // if already highlited - skip
//sentence = sentence.replace(searchFor, replaceWith);
});
// console.log(sentence);
document.querySelector('.highlighted-sentence').innerHTML = sentenceArr.join(' '); // notice sentenceArr
}
// Works.
//highlighter('kinds words all type', sentence);
// Doesn't work.
highlighter('kinds words high', sentence);
<div class="highlighted-sentence"></div>

how can i replace first two characters of a string in javascript?

lets suppose i have string
var string = "$-20455.00"
I am trying to swap first two characters of a string. I was thinking to split it and make an array and then replacing it, but is there any other way? Also, I am not clear how can I achieve it using arrays? if I have to use arrays.
var string = "-$20455.00"
How can I achieve this?
You can use the replace function in Javascript.
var string = "$-20455.00"
string = string.replace(/^.{2}/g, 'rr');
Here is jsfiddle: https://jsfiddle.net/aoytdh7m/33/
You dont have to use arrays. Just do this
string[1] + string[0] + string.slice(2)
You can split to an array, and then reverse the first two characters and join the pieces together again
var string = "$-20455.00";
var arr = string.split('');
var result = arr.slice(0,2).reverse().concat(arr.slice(2)).join('');
document.body.innerHTML = result;
try using the "slice" method and string concatenation:
stringpart1 = '' //fill in whatever you want to replace the first two characters of the first string with here
string2 = stringpart1 + string.slice(1)
edit: I now see what you meant by "swap". I thought you meant "swap in something else". Vlad's answer is best to just switch the first and the second character.
Note that string[0] refers to the first character in the string, and string[1] to the second character, and so on, because code starts counting at 0.
var string = "$-20455.00";
// Reverse first two characters
var reverse = string.slice(0,2).split('').reverse().join('');
// Concat again with renaming string
var result= reverse.concat(string.slice(2));
document.body.innerHTML = result;
let finalStr = string[1] + string[0] + string.slice(2); //this will give you the result

How to remove the last matched regex pattern in javascript

I have a text which goes like this...
var string = '~a=123~b=234~c=345~b=456'
I need to extract the string such that it splits into
['~a=123~b=234~c=345','']
That is, I need to split the string with /b=.*/ pattern but it should match the last found pattern. How to achieve this using RegEx?
Note: The numbers present after the equal is randomly generated.
Edit:
The above one was just an example. I did not make the question clear I guess.
Generalized String being...
<word1>=<random_alphanumeric_word>~<word2>=<random_alphanumeric_word>..~..~..<word2>=<random_alphanumeric_word>
All have random length and all wordi are alphabets, the whole string length is not fixed. the only text known would be <word2>. Hence I needed RegEx for it and pattern being /<word2>=.*/
This doesn't sound like a job for regexen considering that you want to extract a specific piece. Instead, you can just use lastIndexOf to split the string in two:
var lio = str.lastIndexOf('b=');
var arr = [];
var arr[0] = str.substr(0, lio);
var arr[1] = str.substr(lio);
http://jsfiddle.net/NJn6j/
I don't think I'd personally use a regex for this type of problem, but you can extract the last option pair with a regex like this:
var str = '~a=123~b=234~c=345~b=456';
var matches = str.match(/^(.*)~([^=]+=[^=]+)$/);
// matches[1] = "~a=123~b=234~c=345"
// matches[2] = "b=456"
Demo: http://jsfiddle.net/jfriend00/SGMRC/
Assuming the format is (~, alphanumeric name, =, and numbers) repeated arbitrary number of times. The most important assumption here is that ~ appear once for each name-value pair, and it doesn't appear in the name.
You can remove the last token by a simple replacement:
str.replace(/(.*)~.*/, '$1')
This works by using the greedy property of * to force it to match the last ~ in the input.
This can also be achieved with lastIndexOf, since you only need to know the index of the last ~:
str.substring(0, (str.lastIndexOf('~') + 1 || str.length() + 1) - 1)
(Well, I don't know if the code above is good JS or not... I would rather write in a few lines. The above is just for showing one-liner solution).
A RegExp that will give a result that you may could use is:
string.match(/[a-z]*?=(.*?((?=~)|$))/gi);
// ["a=123", "b=234", "c=345", "b=456"]
But in your case the simplest solution is to split the string before extract the content:
var results = string.split('~'); // ["", "a=123", "b=234", "c=345", "b=456"]
Now will be easy to extract the key and result to add to an object:
var myObj = {};
results.forEach(function (item) {
if(item) {
var r = item.split('=');
if (!myObj[r[0]]) {
myObj[r[0]] = [r[1]];
} else {
myObj[r[0]].push(r[1]);
}
}
});
console.log(myObj);
Object:
a: ["123"]
b: ["234", "456"]
c: ["345"]
(?=.*(~b=[^~]*))\1
will get it done in one match, but if there are duplicate entries it will go to the first. Performance also isn't great and if you string.replace it will destroy all duplicates. It would pass your example, but against '~a=123~b=234~c=345~b=234' it would go to the first 'b=234'.
.*(~b=[^~]*)
will run a lot faster, but it requires another step because the match comes out in a group:
var re = /.*(~b=[^~]*)/.exec(string);
var result = re[1]; //~b=234
var array = string.split(re[1]);
This method will also have the with exact duplicates. Another option is:
var regex = /.*(~b=[^~]*)/g;
var re = regex.exec(string);
var result = re[1];
// if you want an array from either side of the string:
var array = [string.slice(0, regex.lastIndex - re[1].length - 1), string.slice(regex.lastIndex, string.length)];
This actually finds the exact location of the last match and removes it regex.lastIndex - re[1].length - 1 is my guess for the index to remove the ellipsis from the leading side, but I didn't test it so it might be off by 1.

Categories

Resources