Find and replace duplicates in a string - javascript

I have a problem, and can't figure out a soulution right now.
I have a string like this "abcd dfeg uyti lksh bxnm abcd uyti".
And i want to replace the duplicates with some other text (i use a function to generate random letters).
But there is a problem, that the new text is alerdy generated.
EXAMPLE INPUT "aaaa bbbb cccc bbbb cccc dddd eeee"
My output is like this "aaaa bbbb cccc aaaa eeee dddd eeee". which is wrong
But the output i want is like this "aaaa bbbb cccc ffff gggg dddd eeee"
I tried this code
function formatTEXT(text) {
let words = text.split(" ");
let replaced = new Set();
let duplicatesFound = true;
while (duplicatesFound) {
const wordCounts = {};
duplicatesFound = false;
for (let i = 0; i < words.length; i++) {
const word = words[i];
if (!wordCounts[word]) {
wordCounts[word] = 1;
} else {
wordCounts[word]++;
}
}
for (let i = 0; i < words.length; i++) {
let replacement = generateTags(lettersN);
const word = words[i];
if (!replaced.has(word) && wordCounts[word] > 1 && !wordCounts[replacement]) {
words[i] = replacement;
replaced.add(word);
duplicatesFound = true;
console.log(replacement);
}
}
}
return words.join(" ");
}
formatTEXT("aaaa bbbb cccc bbbb cccc dddd eeee");
but it still does not work, there are still some duplicates in here.

function formatText(text) {
let hashMappedString = text
.split(' ')
.reduce((previousState, currentElement) => {
previousState[currentElement] = currentElement;
return previousState;
}, {});
var newWords = '';
for (let word in hashMappedString) {
newWords += ` ${word}`;
console.log(word);
}
return newWords.trim(); // to remove the space in the beginning
}
console.log(formatText('aaaa bbbb cccc bbbb cccc dddd eeee'));
// this code has the time complexity of O(n) + O(n) which is O(2n) which is O(n) by ignoring the constant

What you could do is build a list while checking for duplicates, then join it back into a string:
function formatText(text) {
let words = text.split(" ");
var newWords = []
for (let i in words) {
if (!newWords.includes(words[i])) {
newWords.push(words[i])
}
}
return newWords.join(" ")
}
console.log(formatText("aaaa bbbb cccc bbbb cccc dddd eeee"))
Output: "aaaa bbbb cccc dddd eeee"

Related

javascript replaces text on loop from separate strings

I made loop for, from split string and try to find some text and replace it by the result of separate string, here for example :
function replaceStr(str, find, replace) {
for (var i = 0; i < find.length; i++) {
str = str.replace(new RegExp(find[i], 'gi'), replace[i]);
}
return str;
}
var str = 'some text contain car and some house contain car, or car contain someone';
var values = "cat,dog,chicken";
splt = values.split(',');
for (i = 0; i < splt.length; i++) {
var find = ['car'];
var replace = ['' + values[i] + ''];
replaced = replaceStr(str, find, replace);
}
console.log(replaced);
//console.log(splt.length);
but the result return zeros
I want find all "car" text and replace it from splited text by comma characters
anyone can help me please..
hum what is the goal of your replaceStr function ?
maybe this is enough :
var str = 'some text contain car and some house contain car, or car contain someone';
var values = "cat,dog,chicken";
splt = values.split(',');
for (i = 0; i < splt.length; i++) {
var find = 'car';
str = str.replace(find, splt[i]);
}
console.log(str);
I guess implicitly from your question you want to replace "car" with cat, dog, chicken progressively to achieve this:
"some text contain cat and some house contain dog, or chicken contain someone"
So roughly this would be your solution:
var str = 'some text contain car and some house contain car, or car contain someone';
var values = "cat,dog,chicken";
var splt = values.split(',');
var replaced = str;
for (i = 0; i < splt.length; i++) {
replaced = replaced.replace('car', splt[i]);
}
console.log(replaced);

How to add spaces to every two numbers with JavaScript?

I like to output a formatted number with a space after every two numbers, I've tried this:
function twoSpaceNumber(num) {
return num.toString().replace(/\B(?<!\.\d)(?=([0-9]{2})+(?!\d))/g, " ");
}
twoSpaceNumber(12345678) => 1 23 45 67 89 ( should start with 12 ? )
and also when it starts with 0 I had very strange output
twoSpaceNumber(012345678) => 12 34 56 78
Please consider
var s = "1234456";
var t = s.match(/.{1,2}/g);
var u = t.join(" ");
console.log(u);
which logs
12 34 45 6
and
var s = "ABCDEF";
var t = s.match(/.{1,2}/g);
var u = t.join(" ");
console.log(u);
which logs
AB CD EF
Note that s is a string.
Is that what you need?
Pass num as a string, not a number, else the leading zeros will disappear and use
function twoSpaceNumber(num) {
return num.replace(/\d{2}(?!$)/g, "$& ");
}
The regex matches two digits that are not at the end of string (in order not to add a space at the string end).
JavaScript demo
const regex = /\d{2}(?!$)/g;
function twoSpaceNumber(num) {
return num.replace(regex, "$& ");
}
const strings = ['123456789','012345678'];
for (const string of strings) {
console.log(string, '=>', twoSpaceNumber(string));
}
If you don't mind a non-regex approach:
function twoSpaceNumber(num) {
var res = '';
num += '';
for(var i = 0; i < num.length; i+=2)
{
res += num.substr(i,2) + ' ';
}
return res.trim();
}

How to split a string after a date in Javascript?

I have the string "11/21/2018 11/27/2018 Thanksgiving Break" and would like to cut both dates from it and only retrieve both dates (11/21/2018) and (11/27/2018) as well as the title in some form of array.
You can match the dates and everything else while replacing groups like this:
const str = "11/21/2018 11/27/2018 Thanksgiving Break";
const ans = [];
str.replace(/(\d{2}\/\d{2}\/\d{4}) |(.+$)/g, (_, date, text) => {
ans.push(date || text);
});
console.log(ans);
You can see how the regex groups matches here: https://regex101.com/r/IXW6Hv/1
You could use split method.
let str = "11/21/2018 11/27/2018 Thanksgiving Break"
let endOfFirstDate = str.indexOf(" ")
let firstDate = str.substring(0, endOfFirstDate).trim()
let endOfSecondDate = str.indexOf(" ", endOfFirstDate + 1)
let secondDate = str.substring(endOfFirstDate, endOfSecondDate).trim()
let title = str.substring(endOfSecondDate, str.length).trim()
This is commonly done using Regular expressions:
const text = "11/21/2018 11/27/2018 Thanksgiving Break";
console.log(text.match(/([0-9\/]+\s){2}(.+)/)[2])
A more basic way is to split the string into words, remove the first two, then join it again:
const text = "11/21/2018 11/27/2018 Thanksgiving Break";
console.log(text.split(" ").splice(2).join(" "))
if your date is always dd/mm/yyyy style, you can try this one to test it.
let str = "11/21/2018 11/27/2018 Thanksgiving Break"
let tmp = str;
tmp = tmp.replace(/[\d]+\/[\d]+\/[\d]+/g," ")
let arr = tmp.split(" ");
for(const item of arr){
if(item){
str = str.replace(item," ");
}
}
for(const item of str.split(" ")){
if(item){
console.log(item);
}
}
if all your data are separate by space, you can try a simple one like below:
let str = "11/21/2018 11/27/2018 Thanksgiving Break"
let arr = str.split(" ");
for(const item of arr){
if(/[\d]+\/[\d]+\/[\d]+/.test(item)){
console.log(item);
}
}

convert uppercase letters to lower case

I know there are lots of discussions about how to convert characters in a string to all be lower case. My question is why my implementation below is failing.
CODE:
let str = 'aAaA';
const makeLowerCase = (string) => {
for ( var i = 0; i < string.length; i++ ) {
let lower = string[i].toLowerCase();
if (string[i] !== lower ) {
string[i] = lower;
}
}
}
console.log('before', str);
makeLowerCase(str);
console.log('after', str);
Output in console:
before aAaA
after aAaA
Even though for indexes 1 and 3 the if statement test should pass, the code in that block is evidently not running or is running but not having the expected outcome.
Thanks all.
JavaScript strings are immutable. So you can not change the string using C programming style. Rather use the following code
let str = 'aAaA';
const makeLowerCase = (string) => {
for ( var i = 0; i < string.length; i++ ) {
let lower = string[i].toLowerCase();
if (string[i] !== lower ) {
string = string.substring(0,i)+lower+string.substring(i+1);
}
}
return string;
}
console.log('before', str);
str = makeLowerCase(str);
console.log('after', str);
You can also simply call toLowerCase() method on the whole string unless you have any reason to run the loop. Like following:
let str = 'aAaA';
str = str.toLowerCase();
console.log(str);
Close for statement and add the following
Return string
Run
Console.log(makeLowerCase(...))
Or const str = makeLowerCase(...); console.log(str)

How to define a identical number for all identical URLs at the string?

I have a string like this:
var str = "this is [link1][1]
this is [link2][2]
this is [link3][3]
this is [link4][4]
[1]: http://example1.com
[2]: http://example2.com
[3]: http://example1.com
[4]: http://example4.com";
Now I want this:
var str = "this is [link1][1]
this is [link2][2]
this is [link3][1]
this is [link4][4]
[1]: http://example1.com
[2]: http://example2.com
[4]: http://example4.com";
As you see in the above example there is two things:
Removing redundant \n between all those URLs (only URLs)
Remove duplicate URLs and replace refrence-number.(In other word, in the example above, because first and third URLs are the same, then [3]: http://example1.com removed and [3] replaced with [1])
There is a regex which matches [any digit]: and its url in two groups:
/(\[[0-9]*]:)\s*(.*)\r?\n?/gm
In the str, that regex matches:
//group1
$1: [1]:
[2]:
[3]:
[4]:
//group2
$2: http://example1.com
http://example2.com
http://example1.com
http://example4.com
Also there is another regex which remove all waste \n between only links:
str.replace(/(^\[[0-9]*]:.*)\n+/gm, $1\n);
Well, How can I do that?
This could be a solution for yout problem:
function removeMultipleMatkdownLinks(markownString) {
var seperateLinks = /(\[[0-9]*]):\s*(.*)\r?\n?/gm;
var removeNewLines = /(^\[[0-9]*]:.*)\n+/gm;
var result;
var urls = [], ids = [];
var formattedString = str;
while ((result = seperateLinks.exec(str)) !== null) {
if (result.index === seperateLinks.lastIndex) {
result.lastIndex++;
}
//check if link already exists
var index = urls.indexOf(result[2]);
if(index < 0) {
urls.push(result[2]);
ids.push(result[1]);
} else { //remove links and replace ids
var removeLink = new RegExp("(\\" + result[1] + ":.*\\r?\\n?)", "gm"); ///(\[1\]:.*\n)/gm
var changeNumber = new RegExp("(\\" + result[1] + ")", "gm");
formattedString = formattedString
.replace(removeLink, "")
.replace(changeNumber, ids[index]);
}
}
return formattedString.replace(removeNewLines, "$1\n");
}
JSFiddle

Categories

Resources