【问题标题】:In javascript, how do you search an array for a substring match在javascript中,如何在数组中搜索子字符串匹配
【发布时间】:2011-06-01 03:55:13
【问题描述】:

我需要在 javascript 中搜索一个数组。搜索将仅匹配字符串的一部分,因为该字符串将分配有额外的数字。然后我需要用完整的字符串返回成功匹配的数组元素。

var windowArray = new Array ("item","thing","id-3-text","class");

我需要搜索包含"id-" 的数组元素,并且我还需要提取元素中的其余文本(即"id-3-text")。

谢谢

【问题讨论】:

  • 你可以过滤数组results = arr.filter(function (v) {return /id-/.test(v)});。然后你可以对结果做任何你想做的事情。
  • @zzzzBov 你的评论值得回答……
  • 如果您只对id- 感兴趣,请考虑将windowArray.find((string) => string.startsWith("id-")) 作为可能的前缀

标签: javascript arrays search


【解决方案1】:

如果您能够在项目中使用 Underscore.js_.filter() 数组函数可以轻松完成:

// find all strings in array containing 'thi'
var matches = _.filter(
    [ 'item 1', 'thing', 'id-3-text', 'class' ],
    function( s ) { return s.indexOf( 'thi' ) !== -1; }
);

迭代器函数可以做任何你想做的事情,只要它对匹配返回 true。效果很好。

2017 年 12 月 3 日更新:
现在这是一个非常过时的答案。也许不是大批量中性能最高的选项,但它可以写得更简洁很多,现在可以使用原生 ES6 数组/字符串方法,如 .filter().includes()

// find all strings in array containing 'thi'
const items = ['item 1', 'thing', 'id-3-text', 'class'];
const matches = items.filter(s => s.includes('thi'));

注意:String.prototype.includes() 不支持 indexOf()。

【讨论】:

  • @Floppy88 原来的问题是在一个简单的数组中搜索;它现在也有点长(不需要下划线。)你会搜索对象值或键吗?一个示例用例会很有帮助。
  • 我需要在对象键中搜索
  • @Floppy88 只需使用Object.keys(yourArrayName),它会返回一个数组。你可以使用上面相同的技术来.filter()它下来。
  • 在大多数情况下使用 .filter() 函数是最好的方法
【解决方案2】:

这里的人让这太难了。只需执行以下操作...

myArray.findIndex(element => element.includes("substring"))

findIndex() 是一种 ES6 高阶方法,它遍历数组的元素并返回匹配某些条件的第一个元素的索引(作为函数提供)。在这种情况下,我使用 ES6 语法来声明高阶函数。 element 是函数的参数(可以是任何名称),粗箭头将后面的内容声明为匿名函数(不需要用花括号括起来,除非它占用多于一行)。

findIndex()内我使用了非常简单的includes()方法来检查当前元素是否包含你想要的子字符串。

【讨论】:

  • 惊人的答案,正是我想要的。谢谢!
  • 这正是我所需要的,也是一个很棒的现代答案。点赞!要进一步使用,请将其分配给一个新变量,然后对它做任何你需要的事情。例如:myArray[newVar]
  • 字符串为空时会失败
【解决方案3】:

从给定数组中获取子字符串数组的最简单方法是使用过滤器并包含:

myArray.filter(element => element.includes("substring"));

上面的会返回一个子字符串数组。

myArray.find(element => element.includes("substring"));

上面的将返回数组中的第一个结果元素。

myArray.findIndex(element => element.includes("substring"));

上面的将返回数组中第一个结果元素的索引。

【讨论】:

  • 返回第一个匹配项
  • @00-BBB 用过滤器替换查找
  • 感谢@Hos Mercury。是的,过滤器将返回列表
【解决方案4】:

在你的具体情况下,你可以用一个无聊的旧计数器来做:

var index, value, result;
for (index = 0; index < windowArray.length; ++index) {
    value = windowArray[index];
    if (value.substring(0, 3) === "id-") {
        // You've found it, the full text is in `value`.
        // So you might grab it and break the loop, although
        // really what you do having found it depends on
        // what you need.
        result = value;
        break;
    }
}

// Use `result` here, it will be `undefined` if not found

但如果您的数组是sparse,您可以通过设计合理的for..in 循环更有效地完成它:

var key, value, result;
for (key in windowArray) {
    if (windowArray.hasOwnProperty(key) && !isNaN(parseInt(key, 10))) {
        value = windowArray[key];
        if (value.substring(0, 3) === "id-") {
            // You've found it, the full text is in `value`.
            // So you might grab it and break the loop, although
            // really what you do having found it depends on
            // what you need.
            result = value;
            break;
        }
    }
}

// Use `result` here, it will be `undefined` if not found

当心没有 hasOwnProperty!isNaN(parseInt(key, 10)) 检查的幼稚 for..in 循环; here's why.


题外话

另一种写法

var windowArray = new Array ("item","thing","id-3-text","class");

var windowArray = ["item","thing","id-3-text","class"];

...这对您来说更少打字,也许(这一点是主观的)更容易阅读。这两个语句的结果完全相同:包含这些内容的新数组。

【讨论】:

    【解决方案5】:

    只需在普通的 indexOf 中搜索字符串

    arr.forEach(function(a){
        if (typeof(a) == 'string' && a.indexOf('curl')>-1) {
                console.log(a);
        }        
    });
    

    【讨论】:

    • 它不适用于空值。
    • 如果您的数组中有混合类型,那只是不好的做法,但我还是添加了检查。
    【解决方案6】:

    实现这一点的最简单的原生 javascript 代码是

    var windowArray = ["item", "thing", "id-3-text", "class", "3-id-text"];
    var textToFind = "id-";
    
    //if you only want to match id- as prefix 
    var matches = windowArray.filter(function(windowValue){
      if(windowValue) {
          return (windowValue.substring(0, textToFind.length) === textToFind);
      }
    }); //["id-3-text"]
    
    //if you want to match id- string exists at any position
    var matches = windowArray.filter(function(windowValue){
      if(windowValue) {
          return windowValue.indexOf(textToFind) >= 0;
      }
    }); //["id-3-text", "3-id-text"]
    

    【讨论】:

      【解决方案7】:

      如需对一些替代方案及其效率进行有趣的检验,请参阅 John Resig 最近的帖子:

      (这里讨论的问题略有不同,干草堆元素是针的前缀,而不是相反,但大多数解决方案都很容易适应。)

      【讨论】:

        【解决方案8】:
        let url = item.product_image_urls.filter(arr=>arr.match("homepage")!==null)
        

        使用字符串匹配过滤数组。很简单,一行代码。

        【讨论】:

          【解决方案9】:

          参考: In javascript, how do you search an array for a substring match

          这里给出的解决方案是通用的,不像solution 4556343#4556343,它需要先前的解析来识别join()所使用的字符串,它不是任何数组字符串的组成部分。
          另外,在该代码中/!id-[^!]*/ 更正确,/![^!]*id-[^!]*/ 适合问题参数:

          1. “搜索数组...”(字符串或数字,而不是函数、数组、对象等)
          2. “只匹配部分字符串”(匹配可以在任何地方)
          3. “返回 ... 匹配的 ... 元素”(单数,而不是 ALL,如“... the ... elementS”)
          4. “带有完整的字符串”(包括引号)

          ... NetScape / FireFox 解决方案(见下文JSON 解决方案):

          javascript:         /* "one-liner" statement solution */
             alert(
                ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] .
                   toSource() . match( new RegExp( 
                      '[^\\\\]("([^"]|\\\\")*' + 'id-' + '([^"]|\\\\")*[^\\\\]")' ) ) [1]
             );
          

          javascript:
             ID = 'id-' ;
             QS = '([^"]|\\\\")*' ;           /* only strings with escaped double quotes */
             RE = '[^\\\\]("' +QS+ ID +QS+ '[^\\\\]")' ;/* escaper of escaper of escaper */
             RE = new RegExp( RE ) ;
             RA = ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] ;
             alert(RA.toSource().match(RE)[1]) ;
          

          显示"x'!x'\"id-2"
          也许突袭阵列以找到所有匹配项是“更干净”。

          /* literally (? backslash star escape quotes it!) not true, it has this one v  */
          javascript:                            /* purely functional - it has no ... =! */
             RA = ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] ;
             function findInRA(ra,id){
                ra.unshift(void 0) ;                                     /* cheat the [" */
                return ra . toSource() . match( new RegExp(
                       '[^\\\\]"' + '([^"]|\\\\")*' + id + '([^"]|\\\\")*' + '[^\\\\]"' ,
                       'g' ) ) ;
             }
             alert( findInRA( RA, 'id-' ) . join('\n\n') ) ;
          

          显示:

          "x'!x'\"id-2" "' \"id-1 \"" “id-3-文本”

          使用,JSON.stringify():

          javascript:                             /* needs prefix cleaning */
             RA = ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] ;
             function findInRA(ra,id){
                return JSON.stringify( ra ) . match( new RegExp(
                       '[^\\\\]"([^"]|\\\\")*' + id + '([^"]|\\\\")*[^\\\\]"' ,
                       'g' ) ) ;
             }
             alert( findInRA( RA, 'id-' ) . join('\n\n') ) ;
          

          显示:

          ["x'!x'\"id-2" "' \"id-1 \"" “id-3 文本”

          皱纹:

          • “未转义”的全局 RegExp 是 /[^\]"([^"]|\")*id-([^"]|\")*[^\]"/g,而 \ 可以从字面上找到。为了使([^"]|\")* 匹配所有" 转义为\" 的字符串,\ 本身必须转义为([^"]|\\")*。当这被引用为要与id- 连接的字符串时,每个\ 必须再次转义,因此([^"]|\\\\")*
          • 具有\*"、...的搜索ID也必须通过.toSource()JSON或...进行转义。
          • null 搜索结果应返回 ''(或 "",如包含 NO "! 的 EMPTY 字符串)或 [](适用于所有搜索)。
          • 如果要将搜索结果合并到程序代码中进行进一步处理,则需要eval(),如eval('['+findInRA(RA,ID).join(',')+']')

          ----------------------------------------------- ----------------------------------

          题外话:
          突袭和逃跑?这段代码有冲突吗?
          /* it has no ... =! */ 的符号学、语法和语义强调了引用文字冲突的转义。

          “没有=”的意思是:

          • “没有'='符号”,如javascript:alert('\x3D')(不是!运行它,看看有没有!),
          • “没有带有赋值运算符的javascript语句”,
          • “不相等”与“任何其他代码都不相同”(以前的代码解决方案证明存在功能等价物),
          • ...

          也可以使用下面的立即模式 javascript 协议 URI 在另一个级别上进行引用。 (// 注释以新行结束(又名 nl,ctrl-J,LineFeed,ASCII 十进制 10,八进制 12,十六进制 A),由于插入 nl,通过按 Return 键调用 URI,因此需要引用。)

          javascript:/* a comment */  alert('visible')                                ;
          javascript:// a comment ;   alert(  'not'  ) this is all comment             %0A;
          javascript:// a comment %0A alert('visible but  %\0A  is wrong ')   // X     %0A
          javascript:// a comment %0A alert('visible but %'+'0A is a pain to type')   ;
          

          注意:剪切并粘贴任何 javascript: 行作为即时模式 URI(至少,最多?,在 FireFox 中)以使用第一个 javascript: 作为 URI 方案或协议,其余作为 JS 标签。

          【讨论】:

            【解决方案10】:

            我创建了一个易于使用的库 (ss-search),它旨在处理对象,但也适用于您的情况:

            search(windowArray.map(x => ({ key: x }), ["key"], "SEARCH_TEXT").map(x => x.key)
            

            使用此搜索功能的好处是它会在执行搜索之前对文本进行规范化,以返回更准确的结果。

            【讨论】:

              【解决方案11】:

              另一种可能是

              var res = /!id-[^!]*/.exec("!"+windowArray.join("!"));
              return res && res[0].substr(1);
              

              如果你可以有一个特殊的字符分隔符(这里我使用“!”),那么 IMO 可能是有意义的,数组是恒定的或大部分是恒定的(因此连接可以计算一次或很少)并且完整的字符串不是比搜索的前缀长得多。

              【讨论】:

                【解决方案12】:

                这是您预期的 sn-p,它为您提供所有匹配值的数组 -

                var windowArray = new Array ("item","thing","id-3-text","class");
                
                var result = [];
                windowArray.forEach(val => {
                  if(val && val.includes('id-')) {
                    result.push(val);
                  }
                });
                
                console.log(result);

                【讨论】:

                  【解决方案13】:

                  我认为这可能会对您有所帮助。我有一个类似的问题。如果您的数组如下所示:

                  var array = ["page1","1973","Jimmy"]; 
                  

                  当你得到匹配时,你可以做一个简单的“for”循环来返回数组中的实例。

                  var c; 
                  for (i = 0; i < array.length; i++) {
                  if (array[i].indexOf("page") > -1){ 
                  c = i;}
                  } 
                  

                  我们创建一个空变量 c 来承载我们的答案。 然后我们循环遍历数组以查找数组对象(例如“page1”)与我们的 indexOf(“page”) 匹配的位置。在这种情况下,它是 0(第一个结果)

                  如果您需要进一步的支持,我们很乐意扩展。

                  【讨论】:

                  • 虽然这段代码 sn-p 可能会回答这个问题,包括对为什么如何的解释,它有助于解决问题,提高质量和寿命你的答案,特别是关于像这样的老问题。见"How do I write a good answer?"
                  • 嗨 Slothiful - 感谢您的反馈。我已经相应地更新了我的答案
                  【解决方案14】:

                  这对我有用。

                      const filterData = this.state.data2.filter(item=>((item.name.includes(text)) || (item.surname.includes(text)) || (item.email.includes(text)) || (item.userId === Number(text))) ) ;
                  

                  【讨论】:

                    【解决方案15】:

                    使用此函数搜索子字符串项。

                    function checkItem(arrayItem, searchItem) {
                      return arrayItem.findIndex(element => element.includes(searchItem)) >= 0
                    }
                    
                    function getItem(arrayItem, getItem) {
                      return arrayItem.filter(element => element.includes(getItem))
                    }
                    
                    var arrayItem = ["item","thing","id-3-text","class"];
                    
                    
                    console.log(checkItem(arrayItem, "id-"))
                    console.log(checkItem(arrayItem, "vivek"))
                    console.log(getItem(arrayItem, "id-"))

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2011-02-24
                      • 1970-01-01
                      • 2011-10-16
                      • 2013-11-12
                      • 2022-01-23
                      • 1970-01-01
                      • 2011-07-04
                      相关资源
                      最近更新 更多