How to get a substring in JS - javascript

I have a search input and I need to bold a mathcing part of the string in result.
For example:
input: mac
Search results:
mac book pro 16
iMac 27"
Important macOS tips
I tried do something like that:
let results = document.querySelectorAll('.search-result-child');
results.forEach(result => {
let resultText = result.children[0].innerText;
let startText = resultText.toLowerCase().indexOf(searchInput.value.toLowerCase());
let matchingWord = resultText.toLowerCase().substring(startText);
let newWord = `${resultText.substring(0, startText)}<b>${matchingWord}</b>${partAfterMatchingWordHere}`;
result.children[0].innerHTML = newWord;
})
But in that case I don't know how to get the end index
So in word "mac book pro" - the first index need to be 0 and the last need to be 2.
If you have a solution for it or a best way to do that please help me

I was able to do it thanks to https://stackoverflow.com/users/12270289/klaycon
Code:
let results = document.querySelectorAll('.search-result-child');
results.forEach(result => {
let resultText = result.children[0].innerText;
let newWord = resultText.toLowerCase().replace(searchInput.value.toLowerCase(), `<b>${searchInput.value}</b>`);
result.children[0].innerHTML = newWord;
})

You can add (String.length-1) to the start index to get the ending index

Related

Generate random 6 characters based on input

Generate random 6 characters based on input. Like I want to turn 1028797107357892628 into j4w8p. Or 102879708974181177 into lg36k but I want it to be consistant. Like whenever I feed 1028797107357892628 in, it should always spit out j4w8p. Is this possible? (Without a database if possible.) I know how to generate random 6 characters but I dont know how to connect it with an input tbh. I would appreciate any help, thanks.
let rid = (Math.random() + 1).toString(36).substring(7);
You can create a custom hashing function a simple function to your code would be
const seed = "1028797089741811773";
function customHash(str, outLen){
//The 4 in the next regex needs to be the length of the seed divided by the desired hash lenght
const regx = new RegExp(`.{1,${Math.floor(str.length / outLen)}}`, 'g')
const splitted = str.match(regx);
let out = "";
for(const c of splitted){
let ASCII = c % 126;
if( ASCII < 33) ASCII = 33
out += String.fromCharCode(ASCII)
}
return out.slice(0, outLen)
}
const output = customHash(seed, 6)
console.log(output)
It is called hashing, hashing is not random. In your example to get rid:
let rid = (Math.random() + 1).toString(36).substring(7);
Because it is random, it's impossible to be able to produce "consistant result" as you expect.
You need algorithm to produce a "random" consistant result.
Thanks everyone, solved my issue.
Code:
let seed = Number(1028797089741811773)
let rid = seed.toString(36).substring(0,6)
console.log(rid)
Or:
let seed = Number(1028797089741811773)
let rid = seed.toString(36).substring(6)
console.log(rid)

Telegram app to remove multiple words from input message

I'm trying to create a small app that reads a chat message and echoes a filtered text
I need it to take this message:
INPUT:
#notthis/remove
remove this line
This one too
Output:
notthis
At the moment all it does is remove the second word + the first hashtag:
"hello#hello" which becomes hello
I tried adding the / like this input.split("#","/"); but all it does is crash the program.
Not asking to do the program for me, but I'd really appreciate any hints.
Thank you!
const Telegraf = require('telegraf');
const bot = new Telegraf('182049');
const helpMessage = `
Say something to me
/start - start the bot
/help - command reference
`;
bot.start((ctx) => {
ctx.reply("Hi I am echoo bot");
ctx.reply(helpMessage);
});
bot.help((ctx) => {
ctx.reply(helpMessage)
});
bot.on("text", (ctx) => {
let input = ctx.message.text;
let inputArray = input.split("#");
console.log(inputArray);
let message = "";
if (inputArray.length == 1) {
message = "no separator";
} else {
inputArray.shift();
message = inputArray.join(" ");
}
ctx.reply(message);
});
bot.launch()
Regular Expression (regex) is a great way to find substrings in an unknown string, even though it might be a bit daunting to work with. You can use this website to create your regex.
To find a substring starting with # and ending with /, you can use the following expression:
/#\w+\//g
This will match 1 or more word characters that are in between a # and a /.
For example:
#foo/ will match
#f/ will match
#/ will not match
#foo bar/ will not match (whitespace is not a word character)
An example JavaScript code:
const regex = /#\w+\//g;
const text = "something#fooo/bar #lorem/ipsum";
const found = text.match(regex);
// For each found item, remove the first and last characters
const cleaned = found.map((a) => a.slice(1, -1));
console.log(cleaned);
I think I made it
const Telegraf = require('telegraf');
const bot = new Telegraf('18204DjYLa9o9Y');
const regex = /#\w+\//g;
const helpMessage = `
Say something to me
/start - start the bot
/help - command reference
`;
bot.start((ctx) => {
ctx.reply("Hi I am echoo bot");
ctx.reply(helpMessage);
})
bot.help((ctx) => {
ctx.reply(helpMessage)
})
bot.on("text", (ctx) => {
let input = ctx.message.text;
let inputArray = input.split("#");
console.log(inputArray);
let message = "";
inputArray.shift();
message = inputArray.join(" ");
let messageArray = message.split("/");
console.log(messageArray);
for(let index = 0; message[index] != '/'; index++ )
{
ctx.reply("/ta " + message[index]);
}
return null
})
bot.hears("cat", (ctx) =>{
ctx.reply("Meow");
})
bot.launch()
Only a little issue: if my coin has more than 3 letters it gets truncated.
For loop solves the problem but every letter starts with a new line, and the second imput gets messed up
Eg: echobot, [13.05.21 00:54]
E
echobot, [13.05.21 00:54]
O
echobot, [13.05.21 00:54]
S
2nd attempt:
echobot, [13.05.21 00:54]
S
echobot, [13.05.21 00:54]
O
echobot, [13.05.21 00:54]
E

how to replace string with object values

I'm trying to replace the user flags with emojis but I have no idea how to do it.
I tried that but it didn't work
const flags = {
"HOUSE_BRILLIANCE":"<:house_brilliance:773066280303198218>",
"HOUSE_BRAVERY":"<:house_bravery:773066279967522868>",
"HOUSE_BALANCE":"<:house_balance:773066280319057930>",
"EARLY_SUPPORTER":"<:early_supporter:773066280416444466>",
"HYPESQUAD_EVENTS":"<:hypesquad_events:773066279892418613>",
"BUGHUNTER_LEVEL_1":"<:bughunter:773066280269512714>",
"BUGHUNTER_LEVEL_2":"<:bughunter:773066280269512714>",
"DISCORD_EMPLOYEE":"<:early_verified_bot_developer:773066280135688212>",
"PARTNERED_SERVER_OWNER":"<:partnered_server_owner:773066279996751872>",
"TEAM_USER":"",
"SYSTEM":"",// tf is this one
}
let mflags = message.mentions.users.first().flags.toArray().join(' ')
let fres = mflags.replace(/#(\w+)/g, (match,key)=>flags[key]||match);```

Looking for the easiest way to extract an unknown substring from within a string. (terms separated by slashes)

The initial string:
initString = '/digital/collection/music/bunch/of/other/stuff'
What I want: music
Specifically, I want any term (will never include slashes) that would come between collection/ and /bunch
How I'm going about it:
if(initString.includes('/digital/collection/')){
let slicedString = initString.slice(19); //results in 'music/bunch/of/other/stuff'
let indexOfSlash = slicedString.indexOf('/'); //results, in this case, to 5
let desiredString = slicedString.slice(0, indexOfSlash); //results in 'music'
}
Question:
How the heck do I accomplish this in javascript in a more elegant way?
I looked for something like an endIndexOf() that would replace my hardcoded .slice(19)
lastIndexOf() isn't what I'm looking for, because I want the index at the end of the first instance of my substring /digital/collection/
I'm looking to keep the number of lines down, and I couldn't find anything like a .getStringBetween('beginCutoff, endCutoff')
Thank you in advance!
your title says "index" but your example shows you wanting to return a string. If, in fact, you are wanting to return the string, try this:
if(initString.includes('/digital/collection/')) {
var components = initString.split('/');
return components[3];
}
If the path is always the same, and the field you want is the after the third /, then you can use split.
var initString = '/digital/collection/music/bunch/of/other/stuff';
var collection = initString.split("/")[2]; // third index
In the real world, you will want to check if the index exists first before using it.
var collections = initString.split("/");
var collection = "";
if (collections.length > 2) {
collection = collections[2];
}
You can use const desiredString = initString.slice(19, 24); if its always music you are looking for.
If you need to find the next path param that comes after '/digital/collection/' regardless where '/digital/collection/' lies in the path
first use split to get an path array
then use find to return the element whose 2 prior elements are digital and collection respectively
const initString = '/digital/collection/music/bunch/of/other/stuff'
const pathArray = initString.split('/')
const path = pathArray.length >= 3
? pathArray.find((elm, index)=> pathArray[index-2] === 'digital' && pathArray[index-1] === 'collection')
: 'path is too short'
console.log(path)
Think about this logically: the "end index" is just the "start index" plus the length of the substring, right? So... do that :)
const sub = '/digital/collection/';
const startIndex = initString.indexOf(sub);
if (startIndex >= 0) {
let desiredString = initString.substring(startIndex + sub.length);
}
That'll give you from the end of the substring to the end of the full string; you can always split at / and take index 0 to get just the first directory name form what remains.
You can also use regular expression for the purpose.
const initString = '/digital/collection/music/bunch/of/other/stuff';
const result = initString.match(/\/digital\/collection\/([a-zA-Z]+)\//)[1];
console.log(result);
The console output is:
music
If you know the initial string, and you have the part before the string you seek, then the following snippet returns you the string you seek. You need not calculate indices, or anything like that.
// getting the last index of searchString
// we should get: music
const initString = '/digital/collection/music/bunch/of/other/stuff'
const firstPart = '/digital/collection/'
const lastIndexOf = (s1, s2) => {
return s1.replace(s2, '').split('/')[0]
}
console.log(lastIndexOf(initString, firstPart))

Detect same occurrence in string

Let us assume I got two strings. In my case the strings are "stringA" and "stringB":
Example 1:
let stringA = "1ABC DEFGHI";
let stringB = "XYZABC DEFGHI";
Even if the two strings are not exactly the same, they still contain a large amount of letter sequences, which are identical in both. In the case above it is the string "ABC DEFGHI" that occurs in both of them.
Example 2: And heres another example:
let stringA = "0142 41193566"
let stringB = "+49 142 41193566"
In this case the result should be 142 41193566 because this string occurs in both of them.
I would describe the operation as a kind of mask operation, but I have not progressed so far in implementing it. Unfortunately, this code snippet is everything I can offer so far.
let stringA = "0142 41193566"
let stringB = "+49 142 41193566"
let stringC = "....ThISisATest"
let stringD = "+Th.ISisATest33"
let detectBiggestOccurrence = function(stringA, stringB) {
let result = []
for (let c in stringA) {
if (stringB.includes(stringA[c])) {
let index = stringB.indexOf(stringA[c])
result+=stringB[index]
}
}; return result
}
let resultWorking = detectBiggestOccurrence(stringA, stringB)
console.log("working:", resultWorking)
let resultNotWorking = detectBiggestOccurrence(stringC, stringD)
console.log("not working:", resultNotWorking)
Issue: The code above is working for the first call (detectBiggestOccurrence(stringA, stringB)) but it does not work for the second one (detectBiggestOccurrence(stringC, stringD)).
The approach that I've used to solve your problem :
Create an empty mask
Populate that empty mask by one letter in first string and check if the mask is present in the second string.
Compare mask length with last response length. If mask is bigger, mask becomes the response
function detectBiggestOccurrence(stringA, stringB){
var mask ="";
var response ="";
stringA.split('').forEach( el => {
mask +=el;
if(stringB.includes(mask)){
if(mask.length > response.length){ response = mask; }
}
else {
mask =el;
}
})
return response;
}
let stringA = "1ABC DEFGHI";
let stringB = "XYZABC DEFGHI";
console.log(detectBiggestOccurrence(stringA, stringB));
let stringC = "0142 41193566";
let stringD = "+49 142 41193566";
console.log(detectBiggestOccurrence(stringC, stringD));
let stringE = "....ThISisATest"
let stringF = "+Th.ISisATest33"
console.log(detectBiggestOccurrence(stringE, stringF));
Here is a modified version of Pierre Capo's answer. It will return a correct result, even if a "problematic" string should be tested (see my comment under Pierre's answer).
function maxmatch(a,b){
var i=0,res='',pat=a[i];
while (i<a.length) {
if (b.includes(pat)) {
if (pat.length>res.length) res=pat;
pat+=a[++i];
}
else {
if (pat.length>1) pat=pat.slice(1);
else pat=a[++i];
}
}
return res;
}
let testStrings=[["1ABC DEFGHI","XYZABC DEFGHI"],
["1ABC DEFGHI","XYZBC DEFGHI ABC"],
["0142 41193566","+49 142 41193566"],
["....ThISisATest","+Th.ISisATest33"]];
testStrings.forEach(t=>console.log(maxmatch(...t)))
When applied to the test strings (please notice: I added a modified version of the first test string) they will all return the correct answer:
ABC DEFGHI
BC DEFGHI
142 41193566
ISisATest

Categories

Resources