【问题标题】:Intersecting texts to find common words交叉文本以查找常用词
【发布时间】:2014-07-17 08:16:27
【问题描述】:

我正在尝试找出哪一种是交叉一组文本的最佳方式,并在其中找到常用词。鉴于这种情况:

var t1 = 'My name is Mary-Ann, and I come from Kansas!';
var t2 = 'John, meet Mary, she comes from far away';
var t3 = 'Hi Mary-Ann, come here, nice to meet you!';

交集结果应该是:

var result =["Mary"];

应该可以忽略.,!?-这样的标点符号

使用正则表达式的解决方案会是最优的吗?

【问题讨论】:

    标签: javascript regex string text


    【解决方案1】:

    这是一个经过测试的解决方案:

    function intersect() {
       var set = {};
       [].forEach.call(arguments, function(a,i){
         var tokens = a.match(/\w+/g);
         if (!i) {
           tokens.forEach(function(t){ set[t]=1 });
         } else {
           for (var k in set){
             if (tokens.indexOf(k)<0) delete set[k];
           }
         }
       });
       return Object.keys(set);
    }
    

    这个函数是可变参数的,你可以用任意数量的文本调用它:

    console.log(intersect(t1, t2, t3)) // -> ["Mary"] 
    
    console.log(intersect(t1, t2)) // -> ["Mary", "from"] 
    
    console.log(intersect()) // -> [] 
    

    如果你需要支持非英语语言,那么这个正则表达式就不够用了,因为 JavaScript 正则表达式中对 Unicode 的支持很差。要么使用regex library,要么通过明确排除a.match(/[^\s\-.,!?]+/g); 中的字符来定义正则表达式(这对你来说可能就足够了)。


    详细解释:

    这个想法是用第一个文本的标记填充一个集合,然后从集合中删除其他文本中缺少的标记。

    1. 该集合是一个用作地图的 JavaScript 对象。一些纯粹主义者会使用Object.create(null) 来避免原型,我喜欢{} 的简单性。
    2. 因为我希望我的函数是 variadic,所以我使用 arguments 而不是将传递的文本定义为显式参数。
    3. arguments 不是真正的数组,因此要对其进行迭代,您需要 for 循环或类似 [].forEach.call 的技巧。之所以有效,是因为 arguments"array-like"
    4. 为了标记化,我只是使用match 来匹配单词,这里没什么特别的(不过,请参阅上面关于更好地支持其他语言的注释)
    5. 我使用!i 来检查它是否是第一个文本。在这种情况下,我只需将标记复制为集合中的属性。必须使用一个值,我使用1。未来,ES6 sets 将使这里的意图更加明显。
    6. 对于以下文本,我遍历集合的元素(键)并删除不在令牌数组中的元素 (tokens.indexOf(k)&lt;0)
    7. 最后,我返回集合的元素,因为我们需要一个数组。最简单的解决方案是使用Object.keys

    【讨论】:

    • “[].forEach.call() 在 JavaScript 中的作用是什么?” stackoverflow.com/questions/16053357/…
    • @MatthewLock 你的意思是我应该解释这一点吗?
    • 那个链接就可以了。
    • 这是聪明的代码,但我仍在努力遵循它。
    • reduce 代替forEach 可能是一个声明,而且“冗长”一点,但我更喜欢它更具可读性。
    猜你喜欢
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 2018-07-09
    相关资源
    最近更新 更多