删除字符串中出现的重复单词
Posted
技术标签:
【中文标题】删除字符串中出现的重复单词【英文标题】:Remove occurrences of duplicate words in a string 【发布时间】:2013-05-26 11:46:02 【问题描述】:以下面的字符串为例:
var string = "spanner, span, spaniel, span";
我想从这个字符串中找到重复的单词,删除所有重复的单词,保持单词出现一次,然后输出修改后的字符串。
在这个例子中是:
var string = "spanner, span, spaniel";
我已经设置了一个用于测试的 jsFiddle:http://jsfiddle.net/p2Gqc/
请注意,字符串中单词的顺序并不一致,每个字符串的长度也不一致,因此我认为正则表达式不会在这里完成工作。我正在考虑将字符串拆分为数组的方式?但我希望它对客户端尽可能轻且速度超快...
【问题讨论】:
不错的小提琴,但实际上它背后没有逻辑......看看String.split()。然后,您可以遍历单词数组并检查重复项。 a) 从您的字符串构建一个数组。 b) 遍历数组并将每个元素附加到新数组中,如果该元素不在新数组中。 c) 将新数组转换为字符串。 我有一些问题。性能很重要吗?一个字符串可以有多长(最大)?您要删除所有重复的单词还是只删除找到的第一个单词? 【参考方案1】:这样的事情怎么样?
拆分字符串,获取数组,过滤它以删除重复项,然后将它们加入。
var uniqueList=string.split(',').filter(function(item,i,allItems)
return i==allItems.indexOf(item);
).join(',');
$('#output').append(uniqueList);
Fiddle
对于不支持的浏览器,你可以通过在你的 js 中添加这个来解决它。
见Filter
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;
;
【讨论】:
你可能想要修剪你的字符串。这失败了 var string = "spanner,span, spaniel, span"; @PSL 传递给函数(item,i,allItems)的参数,你能解释一下当函数返回“return i==allItems.indexOf(item)”时它是如何工作的。正如你所理解的,allitems 是整个字符串,items 是传递给字符串的每个单独的项目,但是“i”是什么?i
是索引。 indexOf 返回列表allItems
中匹配的第一个项目。所以检查这将为重复项目返回 false 并随后从过滤列表中排除。
当您使用节点 js readfileasync 在“\n”上进行拆分搜索以删除重复行时,可以做得很好。【参考方案2】:
如果以上方法都不适合你,这里还有另一种方法:
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(各种强制兼容性恶作剧),这是唯一有效的解决方案。感谢您发布它:)【参考方案3】:使用正则表达式的替代解决方案
通过使用正向前瞻,您可以去除所有重复的单词。
正则表达式/(\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);
唯一需要注意的是,这个正则表达式只保留找到的重复单词的最后一个实例,并删除所有其余的实例。对于那些只关心重复而不关心单词顺序的人来说,这应该可行!
【讨论】:
【参考方案4】:// 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);
Live DEMO
【讨论】:
【参考方案5】:其他两个答案都可以正常工作,尽管 PSL 使用的 filter
数组方法已添加到 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(', ');
【讨论】:
【参考方案6】:<script type="text/javascript">
str=prompt("Enter String::","");
arr=new Array();
arr=str.split(",");
unique=new Array();
for(i=0;i<arr.length;i++)
if((i==arr.indexOf(arr[i]))||(arr.indexOf(arr[i])==arr.lastIndexOf(arr[i])))
unique.push(arr[i]);
unique.join(",");
alert(unique);
</script>
此代码块将从句子中删除重复的单词。
if 语句的第一个条件,即 (i==arr.indexOf(arr[i])) 将包括结果中第一次出现重复单词(此代码中的变量唯一)。
第二个条件 (arr.indexOf(arr[i])==arr.lastIndexOf(arr[i])) 将包括所有不重复的单词。
【讨论】:
【参考方案7】:下面是一个易于理解且快速的代码,用于删除字符串中的重复单词:
var string = "spanner, span, spaniel, span";
var uniqueListIndex=string.split(',').filter(function(currentItem,i,allItems)
return (i == allItems.indexOf(currentItem));
);
var uniqueList=uniqueListIndex.join(',');
alert(uniqueList);//Result:spanner, span, spaniel
就这么简单就可以解决您的问题。希望这可以帮助。干杯:)
【讨论】:
【参考方案8】:要删除所有重复的单词,我使用以下代码:
<script>
function deleteDuplicate(a)a=a.toString().replace(/ /g,",");a=a.replace(/[ ]/g,"").split(",");for(var b=[],c=0;c<a.length;c++)-1==b.indexOf(a[c])&&b.push(a[c]);b=b.join(", ");return b=b.replace(/,/g," ");
document.write(deleteDuplicate("g g g g"));
</script>
【讨论】:
【参考方案9】:在getUniqueWordString 函数中,我们过滤多余的单词,然后用分隔符连接回来。如果输入字符串中的单词同时存在大写和小写,也添加了一种情况。
function getUniqueWordString(str, delimiter)
return str.toLowerCase().split(delimiter).filter(function(e, i, arr)
return arr.indexOf(e, i+1) === -1;
).join(delimiter);
let str = "spanner, span, spaniel, span, SPAN, SpaNiel";
console.log(getUniqueWordString(str, ", "))
【讨论】:
【参考方案10】:var string = "spanner, span, spaniel, span";
var strArray= string.split(",");
var unique = [];
for(var i =0; i< strArray.length; i++)
eval(unique[strArray] = new Object());
//通过foreach可以很方便的遍历unique。
我喜欢这个有三个的原因。 首先,它适用于 IE8 或任何其他浏览器。
第二。它更加优化并保证具有独特的结果。
最后,它适用于输入中有空格的其他字符串数组,例如
var string[] = "New York", "New Jersey", "South Hampsire","New York";
对于上述情况,字符串[]中只有三个元素会被唯一存储。
【讨论】:
以上是关于删除字符串中出现的重复单词的主要内容,如果未能解决你的问题,请参考以下文章