Reputation: 548
I'm trying to create a function which will search a specific words.
For example if I tap the letter "O" the first result will be the word "Oasis" (and not "U2 - Still Haven't Found What I'm..." and all the other songs that has "O" in their words), or any other middle word.
It need to ignore spaces - " ", the char "-" (" "-" ") and ' or other chars, so it will connect all thw words together.
For example when I tap "dontlookbackin" the search will find the word which is starting with the first letter I pressed, than the other letter in the word and so on.
So far I'm only able to make a simple search - to find every word that contains the first letter I pressed.
The specific part of the "search" function :
SearchSong = () => {
console.log("Pressed")
var e = this.state.searchRes;
if (e == "") {
return;
}
var musicList = [];
var songs = [];
if (this.state.songs != null) {
songs = this.state.songs;
musicList = songs.filter(song =>
song.Song_Name.toLowerCase().includes(e.toLowerCase())
);
Example of the current search -
If more detials and fixes are needed please tell me.
Upvotes: 0
Views: 4183
Reputation: 2375
let strKeyword = "string001";
musicList = [];
songsLength = songs.length;
for (i = 0; i < songsLength; i++) {
if (songs[i].Song_Name.replace(/[^a-zA-Z0-9]/g, "").substr(0, strKeyword.length).toLowerCase() == strKeyword.toLowerCase()) {
musicList.push(songs[i]);
}
}
console.log(musicList);
Upvotes: 1
Reputation: 21
Try this: song.Song_Name.toLowerCase().startsWith(e.toLowerCase())
Upvotes: 0
Reputation: 1074276
Something along these lines should get you started (see comments):
function removeUnwantedChars(str) {
return str.replace(/\W/g, "");
}
function search(str) {
// Create regex like "abc" becomes "^a.*b.*c"
str = removeUnwantedChars(str);
if (!str) {
return [];
}
const searchRex = new RegExp(
"^" +
RegExp.escape(str.charAt(0)) + [...str.substring(1)].map(ch =>
".*" + RegExp.escape(ch)
).join(""),
"i"
);
// Search for matches
return songs.filter(song => searchRex.test(song.Song_Name.replace(/\W/g, "")));
}
...using a regex escape function along the lines of the ones in this question's answers.
Live Example:
if (!RegExp.escape) {
RegExp.escape = function(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
};
}
const songs = [
{Song_Name: "U2 - I Still Haven't Found What I'm Looking For"},
{Song_Name: "Oasis - Champagne Supernova"},
{Song_Name: "Oasis - Don't Look Back In Anger"},
{Song_Name: "The Rolling Stones - Like A Rolling Stone"}
];
function removeUnwantedChars(str) {
return str.replace(/\W/g, "");
}
function search(str) {
// Create regex like "abc" becomes "^a.*b.*c"
str = removeUnwantedChars(str);
if (!str) {
return [];
}
const searchRex = new RegExp(
"^" +
RegExp.escape(str.charAt(0)) + [...str.substring(1)].map(ch =>
".*" + RegExp.escape(ch)
).join(""),
"i"
);
// Search for matches
return songs.filter(song => searchRex.test(song.Song_Name.replace(/\W/g, "")));
}
const testStrings = [
"oasisdontlookbackin",
"oasisanger",
"therollstone",
"rolling" // no match
];
for (const str of testStrings) {
console.log(str, "=>", search(str));
}
.as-console-wrapper {
max-height: 100% !important;
}
The .*
in the regex means "any number of any character here" which means that you don't have to type every significant character after the first one (which is why "oasisanger"
works). But it does incorporate your requirement that the first character match the first character of the name.
Upvotes: 1