删除字符串中出现的重复单词

IT技术 javascript jquery arrays string
2021-02-02 12:32:26

以下面的字符串为例:

var string = "spanner, span, spaniel, span";

从这个字符串中,我想找到重复的单词,删除所有重复的单词,保留一个单词的出现位置,然后输出修改后的字符串。

在这个例子中是:

var string = "spanner, span, spaniel";

我已经设置了一个 jsFiddle 进行测试:http : //jsfiddle.net/p2Gqc/

请注意,字符串中单词的顺序不一致,每个字符串的长度也不一致,因此我认为正则表达式不会在这里完成这项工作。我正在考虑将字符串拆分为数组的方法?但我希望它对客户端尽可能轻巧,而且速度超快......

6个回答

这样的事情怎么样?

拆分字符串,获取数组,对其进行过滤以删除重复项,然后将它们重新连接起来。

var uniqueList=string.split(',').filter(function(item,i,allItems){
    return i==allItems.indexOf(item);
}).join(',');

$('#output').append(uniqueList);

小提琴

对于不支持的浏览器,您可以通过在 js 中添加它来解决它。

见过滤器

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    "use strict";

    if (this == null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var res = [];
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in t)
      {
        var val = t[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, t))
          res.push(val);
      }
    }

    return res;
  };
}
当您使用节点 js readfileasync 并在 '\n' 上进行拆分来搜索删除重复行时,可以做得很好。
2021-03-19 12:32:26
i是索引。indexOf 返回列表中匹配的第一项allItems所以检查这将为重复项返回 false 并随后从过滤列表中排除。
2021-03-23 12:32:26
您可能想要修剪琴弦。这失败 var string = "spanner,span, spaniel, span";
2021-03-30 12:32:26
@PSL 你传递给函数(item,i,allItems) 的参数,你能解释一下当函数返回“return i==allItems.indexOf(item)”时它是如何工作的。正如你所理解的, allitems 是整个字符串,items 是传递给字符串的每个单独的项目,但是“i”是什么?
2021-04-12 12:32:26

如果以上都不适合你,这里是另一种方式:

var str = "spanner, span, spaniel, span";
str = str.replace(/[ ]/g,"").split(",");
var result = [];
for(var i =0; i < str.length ; i++){
    if(result.indexOf(str[i]) == -1) result.push(str[i]);
}
result=result.join(", ");

或者,如果您希望它处于更好的状态,请尝试以下操作:

Array.prototype.removeDuplicate = function(){
   var result = [];
   for(var i =0; i < this.length ; i++){
       if(result.indexOf(this[i]) == -1) result.push(this[i]);
   }
   return result;
}
var str = "spanner, span, spaniel, span";
str = str.replace(/[ ]/g,"").split(",").removeDuplicate().join(", ");
我正在使用公司版本的 ie11(各种强制兼容性恶作剧),这是唯一有效的解决方案。谢谢您的发布 :)
2021-04-12 12:32:26

使用正则表达式的替代解决方案

通过使用积极的前瞻,您可以去除所有重复的单词。

正则表达式/(\b\S+\b)(?=.*\1)/ig,其中

  • \b - 匹配词边界
  • \S - 匹配非空白字符(制表符、换行符等)
  • ?= - 用于正向预测
  • ig - 分别用于区分大小写、全局搜索的标志
  • +,*- 量词。+ -> 1 或更多,* -> 0 或更多
  • () - 定义一个组
  • \1 - 反向引用上一组的结果

var string1 = 'spanner, span, spaniel, span';
var string2 = 'spanner, span, spaniel, span, span';
var string3 = 'What, the, the, heck';
// modified regex to remove preceding ',' and ' ' as per your scenario 
var result1 = string1.replace(/(\b, \w+\b)(?=.*\1)/ig, '');
var result2 = string2.replace(/(\b, \w+\b)(?=.*\1)/ig, '');
var result3 = string3.replace(/(\b, \w+\b)(?=.*\1)/ig, '');
console.log(string1 + ' => ' + result1);
console.log(string2 + ' => ' + result2);
console.log(string3 + ' => ' + result3);

唯一需要注意的是,这个正则表达式只保留找到的重复单词的最后一个实例,并去掉所有其余的。对于那些只关心重复而不关心单词顺序的人来说,这应该有效!

// Take the following string
var string = "spanner, span, spaniel, span";
var arr = string.split(", ");
var unique = [];
$.each(arr, function (index,word) {
    if ($.inArray(word, unique) === -1) 
        unique.push(word);

});

alert(unique);

现场演示

尽管filterPSL 使用数组方法是在 ECMAScript 5 中添加的,并且在旧浏览器中不可用,但其他两个答案都可以正常工作

如果您正在处理长字符串,那么使用$.inArray/Array.indexOf并不是检查您之前是否看过某个项目的最有效方法(每次都需要扫描整个数组)。相反,您可以将每个单词作为键存储在对象中,并利用基于哈希的查找,这将比读取大型数组快得多。

var tmp={};
var arrOut=[];
$.each(string.split(', '), function(_,word){
    if (!(word in tmp)){
        tmp[word]=1;
        arrOut.push(word);
    }
});
arrOut.join(', ');