【问题标题】:Creating a search function for strings in Javascript - React Native在 Javascript 中创建字符串搜索功能 - React Native
【发布时间】:2018-11-30 11:24:45
【问题描述】:

我正在尝试创建一个搜索特定单词的函数。

例如,如果我点击字母“O”,第一个结果将是单词“Oasis”(而不是“U2 - Still Haven't Found What I'm...”和所有其他包含“O”的歌曲他们的话),或任何其他中间词。
它需要忽略空格 - “”,字符“-”(“ -” “)和'或其他字符,因此它将所有thw单词连接在一起。
例如,当我点击“dontlookbackin”时,搜索会找到以我按下的第一个字母开头的单词,而不是单词中的另一个字母,依此类推。

到目前为止,我只能进行简单的搜索 - 找到包含我按下的第一个字母的每个单词。

“搜索”功能的具体部分:

 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())
      );

当前搜索示例 -

如果需要更多细节和修复,请告诉我。

【问题讨论】:

  • 实际问题是什么?删除空格等?由于字符串 'Oasis - Don't Look Back In Anger' 没有空格并且小写是 'oasisdontlookbackinanger',所以你的 .includes() 检查应该找到它。
  • @Shilly 我需要它来查找仅以我按下的字母开头的单词,而不是第二个(第三个等等)。至于现在它不会忽略字符和空格。

标签: javascript reactjs react-native search create-react-app


【解决方案1】:
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);

【讨论】:

  • 谢谢,我认为它应该忽略搜索结果中的字符和“”而不是我按下的单词。仍在进行中,我更新了我的问题。如果需要数字不忽略它们怎么办?
  • 您想从歌曲列表中删除所有字符,而不是从搜索关键字中删除,对吗?
  • 是的,我修复了这个 - ` if (this.state.songs[i].Song_Name.replace(/[^a-zA-Z]/g, "").substr(0, strKeyword .length).toLowerCase() == strKeyword.toLowerCase()) { 用数字修复它谢谢。你能告诉我如何从字符串中的中间词中找到吗? ` .
  • 还更新了跳过数字的答案。请检查。
  • 为此,您可以使用include 方法来查找您已经在问题中使用过的事件。
【解决方案2】:

这些方面的内容应该可以帮助您入门(请参阅 cmets):

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, "")));
}

...按照this question's answers 中的行使用正则表达式转义函数。

现场示例:

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;
}

正则表达式中的.* 表示“此处任意数量的任意字符”,这意味着您不必在第一个字符之后输入每个 重要字符(这就是为什么"oasisanger"作品)。但它确实包含您的要求,即 first 字符与名称的第一个字符匹配。

【讨论】:

  • 也就是说,我会放弃用户正确获取第一个字符的要求。更灵活。但这是一个品味问题。
  • 谢谢@T.J.克劳德!
【解决方案3】:

试试这个: song.Song_Name.toLowerCase().startsWith(e.toLowerCase())

【讨论】:

  • 我试过了,它有效(!)但我也想从中间词中找到。 (我编辑了问题)。
猜你喜欢
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 2013-06-08
  • 2012-10-13
  • 2018-07-25
  • 2015-03-10
  • 2017-03-31
相关资源
最近更新 更多