2012-12-12 76 views
8

我必须在JavaScript中创建一个删除字符串中所有重复字母的函数。到目前为止,我已经能够做到这一点:如果我有“anaconda”这个词,它显示了我应该显示“鳕鱼”时的结果“anaconda”。这里是我的代码:删除字符串中的重复字符

function find_unique_characters(string){ 
    var unique=''; 
    for(var i=0; i<string.length; i++){ 
     if(unique.indexOf(string[i])==-1){ 
      unique += string[i]; 
     } 
    } 
    return unique; 
} 
console.log(find_unique_characters('baraban')); 
+0

看起来你缺少一些代码? jsfiddle.net也适用于这类问题。 – WildCrustacean

+3

http://jsfiddle.net/mplungjan/FHUgY/为我工作 - 我得到谷仓 – mplungjan

+0

我,甚至IE 8 – nozzleman

回答

7

function find_unique_characters(str) { 
 
    var unique = ''; 
 
    for (var i = 0; i < str.length; i++) { 
 
    if (str.lastIndexOf(str[i]) == str.indexOf(str[i])) { 
 
     unique += str[i]; 
 
    } 
 
    } 
 
    return unique; 
 
} 
 

 
console.log(find_unique_characters('baraban')); 
 
console.log(find_unique_characters('anaconda'));

如果你只想要回出现在一个字符串出现一次的字符,检查他们的最后一次出现是在相同的位置,他们的第一次出现。

您的代码至少返回一次字符串中的所有字符,而不是仅返回发生不超过一次的字符。 但显然你已经知道了,否则就不会有问题;-)

+1

而不是在此上下调其中一个更高效的答案问题抱怨复杂性,你如何添加自己的答案,没有n^2复杂性,@ ZacB?不要告诉某人完全重写他们的答案,而不会提出一些建议。这不是建设性的,坦率地说,是粗鲁的。 – Cerbrus

+0

'lastIndexOf'和'indexOf'是O(N)操作(其中N是输入字符串的长度)。许多JS引擎/字符串对象实现会使用字典缓存这些内容或返回的字符串,但这不是100%的时间,也不是给定的。更好地交换临时空间并像其他答案一样使用对象。你可以通过改变输入字符串来缓解空间折衷,但是在那里的复制使得它成为一个有争议的问题。 –

+2

就像我说的,提供你自己的答案。不要只是告诉某人完全重写一个_working,upvoted_答案,因为它不如它能够做到的那样高效。 – Cerbrus

0

我有FF/Chrome浏览器,在其工作的:

var h={}; 
"anaconda".split(""). 
    map(function(c){h[c] |= 0; h[c]++; return c}). 
    filter(function(c){return h[c] == 1}). 
    join("") 

如果你写一个,你可以重复使用功能,如:

function nonRepeaters(s) { 
    var h={}; 
    return s.split(""). 
    map(function(c){h[c] |= 0; h[c]++; return c}). 
    filter(function(c){return h[c] == 1}). 
    join(""); 
} 

对于缺乏mapfilter等等,我猜它可能的jQuery或原型来模拟旧的浏览器...

+0

除了跨浏览器兼容性“颠簸”之外,像这样的数组操作[相对较慢](http://jsperf.com/unique-in-string)。 – Cerbrus

+0

@Cerbrus毫不奇怪。如果我打算在紧张的环境中或在各地使用它,我可能会写一些像你一样的东西。只是有一个声明性的例子是很好的 - 如果他们希望更多地了解关键性的代码而不是性能关键的代码段,可能会有接受者......感谢您的基准测试! – Faiz

+0

事实上,即使某些解决方案因没有明显原因而遭到粗暴低估,仍然有很多解决方案可以解决问题。 (尝试提供非jQuery解决方案时,一些jQueries得到5票);-) 总是有多条路到罗马。 – Cerbrus

0

另一种方式来删除多次出现的所有字母:

function find_unique_characters(string) { 
    var mapping = {}; 
    for(var i = 0; i < string.length; i++) { 
     var letter = string[i].toString(); 
     mapping[letter] = mapping[letter] + 1 || 1; 
    } 
    var unique = ''; 
    for (var letter in mapping) { 
     if (mapping[letter] === 1) 
      unique += letter; 
    } 

    return unique; 
} 

Live test case

说明:您在字符串中的所有字符上循环一次,将每个字符映射到字符串中出现的次数。然后你遍历这些项目(字符串中出现的字母),只挑选出现一次的项目。

+0

有了2个循环和一个临时对象,这对我来说似乎有点像rube goldberg。 – Cerbrus

+0

是的,好主意,但可以在一个循环中实现替换 – mplungjan

+0

谢谢,但有没有另一种方式键入(var字母映射)因为我真的不明白那部分 –

0
function removeDup(str) { 
    var arOut = []; 
    for (var i=0; i < str.length; i++) { 
    var c = str.charAt(i); 
    if (c === '_') continue; 
    if (str.indexOf(c, i+1) === -1) { 
     arOut.push(c); 
    } 
    else { 
     var rx = new RegExp(c, "g"); 
     str = str.replace(rx, '_'); 
    } 
    } 
    return arOut.join(''); 
} 
1

DEMO

function find_unique_characters(string){ 
    unique=[]; 
    while(string.length>0){ 
     var char = string.charAt(0); 
     var re = new RegExp(char,"g"); 
     if (string.match(re).length===1) unique.push(char); 
     string=string.replace(re,""); 
    }   
    return unique.join(""); 
} 
console.log(find_unique_characters('baraban')); // rn 
console.log(find_unique_characters('anaconda')); //cod 
​ 
0

此代码为我工作从一个字符串删除重复(重复)的字符(即使其词用空格隔开)

链接:Working Sample JSFiddle

/* This assumes you have trim the string and checked if it empty */ 
function RemoveDuplicateChars(str) { 
    var curr_index = 0; 
    var curr_char; 
    var strSplit; 
    var found_first; 
    while (curr_char != '') { 
     curr_char = str.charAt(curr_index); 
     /* Ignore spaces */ 
     if (curr_char == ' ') { 
     curr_index++; 
     continue; 
     } 
     strSplit = str.split(''); 
     found_first = false; 
     for (var i=0;i<strSplit.length;i++) { 
     if(str.charAt(i) == curr_char && !found_first) 
      found_first = true; 
     else if (str.charAt(i) == curr_char && found_first) { 
      /* Remove it from the string */ 
      str = setCharAt(str,i,''); 
     } 
     } 
     curr_index++; 
    } 
    return str; 
} 
function setCharAt(str,index,chr) { 
    if(index > str.length-1) return str; 
    return str.substr(0,index) + chr + str.substr(index+1); 
} 
0

这是我用过的 - 没有测试它的空间或特殊效果官方人物,但应该工作的优良纯字符串:

function uniquereduce(instring){ 
    outstring = '' 
    instringarray = instring.split('') 
    used = {} 
    for (var i = 0; i < instringarray.length; i++) { 
     if(!used[instringarray[i]]){ 
      used[instringarray[i]] = true 
      outstring += instringarray[i] 
     } 
    } 
    return outstring 
} 
+0

OP希望所有出现不止一次的字符都被删除。对于''anaconda'',他需要''cod“'作为输出。你的函数返回''ancod“'。 – Cerbrus

-1
function RemDuplchar(str) 
{ 
    var index={},uniq='',i=0; 
    while(i<str.length) 
    { 
     if (!index[str[i]]) 
     { 
     index[str[i]]=true; 
     uniq=uniq+str[i]; 
     } 
      i++; 
    } 
    return uniq; 
} 
+0

OP希望所有出现多次的字符都被删除。对于''anaconda'',他需要''cod“'作为输出。你的函数返回''ancod“'。 – Cerbrus

3

我们现在也可以干净的东西了使用过滤器的方法:

function removeDuplicateCharacters(string) { 
    return string 
    .split('') 
    .filter(function(item, pos, self) { 
     return self.indexOf(item) == pos; 
    }) 
    .join(''); 
} 
console.log(removeDuplicateCharacters('baraban')); 

工作例如: https://jsfiddle.net/masterspambot/ppz6uec1/

-1

我们可以使用for循环删除字符串中的重复或类似元素,并提取字符串方法,如slicesubstring,如果你想删除重复的元素,如aababbafabbbsubstr

例子:

var data = document.getElementById("id").value 
for(var i = 0; i < data.length; i++) 
{ 
    for(var j = i + 1; j < data.length; j++) 
    { 
     if(data.charAt(i)==data.charAt(j)) 
     { 
      data = data.substring(0, j) + data.substring(j + 1); 
      j = j - 1; 
      console.log(data); 
     } 
    } 
} 

请让我知道如果你想要一些额外的信息。

+0

OP希望所有出现多次的字符都被删除。对于''anaconda'',他需要''cod“'作为输出。你的函数返回''ancod“'。 – Cerbrus

0

刚刚遇到类似的问题(找到重复)。从本质上讲,使用哈希来跟踪字符出现次数,并建立一个新的字符串“一击中奇迹”:

function oneHitWonders(input) { 
    var a = input.split(''); 
    var l = a.length; 
    var i = 0; 
    var h = {}; 
    var r = ""; 

    while (i < l) { 
     h[a[i]] = (h[a[i]] || 0) + 1; 

     i += 1; 
    } 

    for (var c in h) { 
     if (h[c] === 1) { 
      r += c; 
     } 
    } 

    return r; 
} 

使用

var a = "anaconda"; 
var b = oneHitWonders(a); // b === "cod" 
3

只想添加我为乐趣的解决方案:

function removeDoubles(string) { 
    var mapping = {}; 
    var newString = ''; 

    for (var i = 0; i < string.length; i++) { 
    if (!(string[i] in mapping)) { 
     newString += string[i]; 
     mapping[string[i]] = true; 
    } 
    } 
    return newString; 
} 
2
//One simple way to remove redundecy of Char in String 
     var char = "aaavsvvssff"; //Input string 
     var rst=char.charAt(0); 
     for(var i=1;i<char.length;i++){    
      var isExist = rst.search(char.charAt(i)); 
      isExist >=0 ?0:(rst += char.charAt(i)); 
     } 
     console.log(JSON.stringify(rst)); //output string : avsf 
0

随着lodash

_.uniq('baraban').join(''); // returns 'barn' 
0

试试这个代码,它的工作原理:)

var str="anaconda"; 
Array.prototype.map.call(str, 
(obj,i)=>{ 
    if(str.indexOf(obj,i+1)==-1 && str.lastIndexOf(obj,i-1)==-1){ 
    return obj; 
    } 
} 
).join(""); 
//output: "cod" 
0

这应该使用正则表达式;
其实,我不知道这个正则表达式是如何工作的,但我知道它的'速记',所以,我会更好地向你解释这个/(.+)(?=.*?\1)/g;的含义。 这个正则表达式只返回给我一个数组中的重复字符,所以我通过它来获得重复字符的长度。但这不适用于像"#" "_" "-",这样的特殊字符,但它会给您预期的结果;包括那些特殊字符if any

function removeDuplicates(str){ 
    var REPEATED_CHARS_REGEX = /(.+)(?=.*?\1)/g; 
    var res = str.match(REPEATED_CHARS_REGEX); 
    var word = res.slice(0,1); 
    var raw = res.slice(1); 
    var together = new String (word+raw); 
    var fer = together.toString(); 
    var length = fer.length; 
    // my sorted duplicate; 
     var result = ''; 
     for(var i = 0; i < str.length; i++) { 
     if(result.indexOf(str[i]) < 0) { 
      result += str[i]; 
     } 
     } 

     return {uniques: result,duplicates: length}; 
    } removeDuplicates('anaconda') 

正则表达式/([a-zA-Z])\1+$/正在寻找:

([a-zA-Z]]) - 它在第一组中捕获的信;然后 \1+ - 紧随其后的那封信的一个或多个副本;然后 $ - 字符串的结尾。 它更改为/([a-zA-Z]).*?\1/代替搜索:

([a-zA-Z]) - 它在第一组中捕获的信;然后 .*? - 零个或多个字符(?表示尽可能少);直到 \1 - 它找到第一个匹配字符的重复。

0
var str = 'anaconda'.split(''); 
var rmDup = str.filter(function(val, i, str){ 
    return str.lastIndexOf(val) === str.indexOf(val); 
}); 
console.log(rmDup); //prints ["c", "o", "d"] 

请确认这里:https://jsfiddle.net/jmgy8eg9/1/