【问题标题】:Find the characters in a string which are not duplicated查找字符串中不重复的字符
【发布时间】:2012-11-30 05:50:15
【问题描述】:

我必须在 JavaScript 中创建一个函数来删除字符串中所有重复的字母。到目前为止,我已经能够做到这一点:如果我有“anaconda”这个词,它会在应该显示“cod”时显示“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'));

【问题讨论】:

  • 看起来您缺少一些代码? jsfiddle.net 也很适合这类问题。
  • jsfiddle.net/mplungjan/FHUgY 为我工作 - 我得到谷仓
  • OP 似乎希望返回那些出现不超过一次的字母。他的代码还为"aaaa"返回"a"
  • 啊,描述有误。你得到 anaconda 的 "ancod" 而不是 "c​​od" - 因此我很困惑
  • 如果你应该养成使用三等号 ( === ) 的习惯,尤其是在这种函数可以返回字符串或数字的情况下。在这个特定的问题中它不会导致错误,但是如果例如 indexOf 在找不到字符时返回 0,如果字符串中有一个 '0' 就会导致问题

标签: javascript string duplicates


【解决方案1】:

我们现在也可以使用过滤器方法来清理:

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

Working example:

【讨论】:

    【解决方案2】:

    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'));

    如果您只想返回在字符串中出现一次的字符,请检查它们最后出现的位置是否与第一次出现的位置相同。

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

    【讨论】:

    • 与其对抱怨复杂性的这个问题的一个更有效的答案投反对票,不如添加自己的答案,而不是 n^2 复杂性,@ZacB?在没有至少给出一些建议的情况下,不要告诉某人完全重写他们的答案。这不是建设性的,而且坦率地说,很粗鲁。
    • lastIndexOfindexOf 是 O(N) 操作(其中 N 是输入字符串的长度)。许多 JS 引擎/字符串对象实现缓存这些内容或使用字典返回字符串,但这并不是 100% 的时间,也不是给定的。最好交换临时空间并像其他答案一样使用对象。你可以通过改变输入字符串来减轻空间权衡,但是那里需要的复制使它成为一个有争议的问题。
    • 就像我说的,提供你自己的答案。不要仅仅因为它没有可能那么有效,就告诉某人完全重写一个有效的、赞成的答案。
    • 哦,lastIndexOfindexOf 组合最多为 O(N)。但坦率地说,就这么小的事情,整个效率讨论都是荒谬的。
    【解决方案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;
    }
    

    【讨论】:

      【解决方案4】:

      lodash:

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

      【讨论】:

        【解决方案5】:

        您可以将要删除的字符作为参数,像这样独特

        function find_unique_characters(str, char){
          return [...new Set(str.split(char))].join(char);
        }
        

        function find_unique_characters(str, char){
          return [...new Set(str.split(char))].join(char);
        }
        
        let result = find_unique_characters("aaaha ok yet?", "a");
        console.log(result);

        【讨论】:

          【解决方案6】:
            //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
          

          【讨论】:

            【解决方案7】:

            对于字符串(一行)

            removeDuplicatesStr = str =&gt; [...new Set(str)].join('');

            对于数组(一行)

            removeDuplicatesArr = arr =&gt; [...new Set(arr)]

            【讨论】:

              【解决方案8】:

              使用集合:

              removeDuplicates = str => [...new Set(str)].join('');
              

              感谢下面的大卫评论。

              【讨论】:

              • 你真的不需要分割字符串,你可以简单地使用 Set 直接到字符串。你甚至可以在一行中完成removeDuplicates = str =&gt; [...new Set(str)].join('');
              【解决方案9】:

              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
              ​
              

              【讨论】:

                【解决方案10】:
                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/

                【讨论】:

                • 不知道效率如何,但我喜欢简单。或者,您可以执行两个indexOf,其中一个使用前一个的起始位置,但我喜欢上面使用lastIndexOf 的决定。
                【解决方案11】:

                使用Set() 并解构两次更短:

                const str = 'aaaaaaaabbbbbbbbbbbbbcdeeeeefggggg';
                
                const unique = [...new Set([...str])].join('');
                
                console.log(unique);

                【讨论】:

                  【解决方案12】:

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

                  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.

                  解释:你循环遍历字符串中的所有字符,将每个字符映射到它在字符串中出现的次数。然后你遍历项目(出现在字符串中的字母)并只选择那些只出现一次的项目。

                  【讨论】:

                  • 有 2 个循环和一个临时对象,这对我来说似乎有点像 rube goldberg。
                  • 是的,好主意,但可以通过替换在一个循环中实现
                  • 谢谢,但是有没有其他的输入方式(映射中的 var 字母)因为我真的不明白那部分
                  • @Cerbrus 我只是觉得这样更具可读性,效率成本真的很小,除非我们谈论的是巨大的字符串,事实并非如此。
                  • @ZlatkoSoleniq 我担心,这是迭代哈希表键的唯一方法。
                  【解决方案13】:
                  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('');
                  }
                  

                  【讨论】:

                    【解决方案14】:

                    我有 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或者原型来模拟……

                    【讨论】:

                    • 除了跨浏览器兼容性“颠簸”之外,像这样的数组操作是relatively slow
                    • @Cerbrus 并不奇怪。如果我要在紧密的循环中或到处使用它,我可能会像你一样写一些东西。只是有一个声明性示例很好 - 如果他们想要更多的理解关键而不是性能关键的代码部分,可能会有接受者......不过感谢基准!
                    • 确实,这里有多个解决方案总是很好的,即使某些解决方案无缘无故地被粗暴地否决了。 (当一些 jQueries 获得 5 票时,尝试提供非 jQuery 解决方案);-) 通往罗马的道路总是多条。
                    【解决方案15】:

                    这段代码对我有用,可以从字符串中删除重复的(重复的)字符(即使它的单词用空格分隔)

                    链接: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);
                    }
                    

                    【讨论】:

                      【解决方案16】:

                      这是我使用的 - 没有测试空格或特殊字符,但对于纯字符串应该可以正常工作:

                      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
                      }
                      

                      【讨论】:

                      • OP 希望删除所有出现多次的字符。对于"anaconda",他需要"cod" 作为输出。你的函数返回"ancod"
                      【解决方案17】:

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

                      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"
                      

                      【讨论】:

                        【解决方案18】:

                        试试这个代码,它可以工作:)

                        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"
                        

                        【讨论】:

                          【解决方案19】:

                          这应该可以使用 Regex ;
                          注意:实际上,我不知道这个正则表达式是如何工作的,但我知道它的“速记”, 所以,我会更好地向你解释这个/(.+)(?=.*?\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 - 它找到第一个匹配字符的重复。

                          【讨论】:

                            【解决方案20】:

                            我有 3 种无循环的单线方法。

                            方法 1 - 删除重复项,并保留原始字符顺序:

                            var str = "anaconda";
                            var newstr = str.replace(new RegExp("[^"+str.split("").sort().join("").replace(/(.)\1+/g, "").replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")+"]","g"),"");
                            //cod
                            

                            方法 2 - 删除重复项但不保留字符顺序,但可能比方法 1 更快,因为它使用较少的正则表达式:

                            var str = "anaconda";
                            var newstr = str.split("").sort().join("").replace(/(.)\1+/g, "");
                            //cdo
                            

                            方法 3 - 删除重复项,但保留唯一值(也不保留字符顺序):

                            var str = "anaconda";
                            var newstr = str.split("").sort().join("").replace(/(.)(?=.*\1)/g, "");
                            //acdno
                            

                            【讨论】:

                            • 这些不是“无环”的。无论解决方案如何,它都需要一个循环。您刚刚设法使用了内置循环函数,这些函数有可能提高效率;不过,这取决于实现。
                            • @vol7ron 从编译器的角度来看,我的答案需要循环,就像它需要 if 语句、开关、布尔值、整数、类和对象一样。从程序员的角度来看,它不需要循环。
                            • 是的,但与窗口进程或事件循环的自然状态不同,这些机制,如 regex 是经过设计优化的循环机制。将它们称为循环构造并不是一件容易的事,它们只是不是 while/for 循环。正则表达式将遍历字符串的字符,替换可以是回调函数; sort 也有一个函数。回调 function 有助于展示它们与 Object.keys() 之类的方法之间的区别,Object.keys() 也循环遍历对象,但不会在每一步都执行用户提供的操作。也许这些是语义上的区别?
                            【解决方案21】:

                            函数删除复制(str){

                            let map = new Map();
                            // n 
                            for (let i = 0; i < str.length; i++) {
                                if (map.has(str[i])) {
                                    map.set(str[i], map.get(str[i]) + 1);
                                } else {
                                    map.set(str[i], 1);
                                }
                            
                            }
                            
                            
                            let res = '';
                            
                            for (let i = 0; i < str.length; i++) {
                                if (map.get(str[i]) === 1) {
                                    res += str[i];
                                }
                            }
                            
                            // o (2n) - > O(n)
                            
                            // space o(n)
                            
                            return res;
                            

                            }

                            【讨论】:

                              【解决方案22】:
                              1. 如果您希望您的函数在参数中只返回一组独特的字符,那么这段代码可能会派上用场。 在这里,您还可以检查记录在“nonUnique”标题数组中的非唯一值:

                                function remDups(str){
                                    if(!str.length)
                                        return '';
                                    var obj = {};
                                    var unique = [];
                                    var notUnique = [];
                                    for(var i = 0; i < str.length; i++){
                                        obj[str[i]] = (obj[str[i]] || 0) + 1;
                                    }
                                    Object.keys(obj).filter(function(el,ind){
                                        if(obj[el] === 1){
                                            unique+=el;
                                        }
                                        else if(obj[el] > 1){
                                            notUnique+=el;
                                        }
                                    });
                                return unique;
                                }
                                console.log(remDups('anaconda')); //prints 'cod'
                                
                              2. 如果你想返回在传递的字符串中只出现一次的字符集,下面的代码可能会派上用场:

                                function remDups(str){
                                    if(!str.length)
                                        return '';
                                    var s = str.split('');
                                    var obj = {};
                                    for(var i = 0; i < s.length; i++){
                                        obj[s[i]] = (obj[s[i]] || 0) + 1;
                                    }
                                    return Object.keys(obj).join('');
                                }
                                console.log(remDups('anaconda')); //prints 'ancod'
                                

                              【讨论】:

                                【解决方案23】:
                                    function removeDuplicates(str) {
                                       var result = "";
                                       var freq = {};
                                       for(i=0;i<str.length;i++){
                                        let char = str[i];
                                        if(freq[char]) {
                                          freq[char]++;     
                                        } else {
                                           freq[char] =1
                                           result +=char;
                                       }
                                    }
                                  return result;
                                }
                                

                                【讨论】:

                                  【解决方案24】:
                                  console.log(("anaconda").split('').sort().join('').replace(/(.)\1+/g, ""));
                                  

                                  这样一来就可以搞定了。

                                  输出:'cdo'

                                  【讨论】:

                                    【解决方案25】:
                                       function removeDuplicates(string){
                                          return string.split('').filter((item, pos, self)=> self.indexOf(item) == pos).join('');
                                       }
                                    

                                    过滤器将删除所有在使用项目索引和当前元素位置之前看到的字符

                                    【讨论】:

                                      【解决方案26】:

                                      方法一:一种简单的方法,只包含JS-函数

                                      var data = 'sssssddddddddddfffffff';
                                      
                                          var ary = [];
                                          var item = '';
                                          for (const index in data) {
                                            if (!ary.includes(data[index])) {
                                              ary[index] = data[index];
                                              item += data[index];
                                            }
                                          }
                                          console.log(item);
                                      

                                      方法 2: 是的,我们可以不使用 JavaScript 函数

                                      var name = 'sssssddddddddddfffffff';
                                      
                                      let i = 0;
                                      let newarry = [];
                                      
                                      for (let singlestr of name) {
                                          newarry[i] = singlestr;
                                          i++;
                                      }
                                      
                                      
                                      // now we have new Array and length of string
                                      length = i;
                                      
                                      function getLocation(recArray, item, arrayLength) {
                                      
                                          firstLaction = -1;
                                          for (let i = 0; i < arrayLength; i++) {
                                      
                                              if (recArray[i] === item) {
                                                  firstLaction = i;
                                                  break;
                                              }
                                      
                                          }
                                      
                                          return firstLaction;
                                      
                                      }
                                      
                                      
                                      let finalString = '';
                                      for (let b = 0; b < length; b++) {
                                         
                                          const result = getLocation(newarry, newarry[b], length);
                                          if (result === b) {
                                              finalString += newarry[b];
                                          }
                                      
                                      }
                                      console.log(finalString); // sdf
                                      

                                      【讨论】:

                                        【解决方案27】:
                                        // Try this way 
                                        
                                        const str = 'anaconda';
                                        const printUniqueChar = str => {
                                           const strArr = str.split("");
                                           const uniqueArray = strArr.filter(el => {
                                              return strArr.indexOf(el) === strArr.lastIndexOf(el);
                                           });
                                           return uniqueArray.join("");
                                        };
                                        console.log(printUniqueChar(str)); // output-> cod
                                        

                                        【讨论】:

                                          【解决方案28】:
                                              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;
                                          } 
                                          

                                          【讨论】:

                                          • OP 希望删除所有出现多次的字符。对于"anaconda",他需要"cod" 作为输出。你的函数返回"ancod"
                                          【解决方案29】:

                                          我们可以使用for循环和提取字符串方法如slicesubstringsubstr等方法去除字符串中重复或相似的元素

                                          如果要删除重复元素例如aababbafabbb

                                          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);
                                                  }
                                              }
                                          }
                                          

                                          如果您想了解更多信息,请告诉我。

                                          【讨论】:

                                          • OP 希望删除所有出现多次的字符。对于"anaconda",他需要"cod" 作为输出。你的函数返回"ancod"
                                          猜你喜欢
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 2014-05-09
                                          • 2020-02-24
                                          • 2011-01-18
                                          • 1970-01-01
                                          相关资源
                                          最近更新 更多