代码之家  ›  专栏  ›  技术社区  ›  xd1936

在Javascript中获取所有可能的替换组合的数组?

  •  6
  • xd1936  · 技术社区  · 7 年前

    replace -关于使用以下替换的元素组合:

    var equiv = {
      "a": "4",
      "b": "8",
      "e": "3",
      "i": "1",
      "l": "1",
      "o": "0",
      "t": "7"
    }
    

    String.prototype 函数,类似于:

    String.prototype.l33tCombonations = function()
    {
        var toReturn = [];
    
        for (var i in equiv)
        {
            // this.???
            // toReturn.push(this???)
        }
    
        return toReturn;
    }
    

    "tomato".l33tCombinations() 然后回来:

    ["tomato", "t0mato", "t0mat0", "tomat0", "toma7o", "t0ma7o", "t0m470", ...].
    

    秩序并不重要。思想?

    5 回复  |  直到 7 年前
        1
  •  3
  •   mhodges    7 年前

    我将使用递归方法,逐字符遍历字符串:

    const toL33t = { "a": "4", "b": "8",  "e": "3",  "i": "1", "l": "1",  "o": "0",  "t": "7" };
    
    function* l33t(string, previous = "") {
      const char = string[0];
      // Base case: no chars left, yield previous combinations
      if(!char) {
        yield previous;
        return;
      }
      // Recursive case: Char does not get l33t3d
      yield* l33t(string.slice(1), previous + char);
      // Recursive case: Char gets l33t3d
      if(toL33t[char])
        yield* l33t(string.slice(1), previous + toL33t[char]);
    }
    
    console.log(...l33t("tomato"));

    如果你真的需要它的原型,这也是可能的,但我不建议:

     String.prototype.l33t = function() {
       return [...l33t(this)];
     };
    
     console.log("stuff".l33t());
    
        2
  •  2
  •   Nina Scholz    7 年前

    可以采用笛卡尔积来生成所需的值。

    function leet(string) {
        const
            cartesian = (a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []),
            code = { a: "4", b: "8", e: "3", i: "1", l: "1", o: "0", t: "7" };
    
        return Array
             .from(string, c => c in code ? [c, code[c]] : [c])
             .reduce(cartesian)
             .map(a => a.join(''));
    }
    
    console.log(leet('tomatoe'));
    .as-console-wrapper { max-height: 100% !important; top: 0; }
        3
  •  2
  •   adiga    7 年前

    你可以用 reduce

    部分 equiv ,只需将字符添加到累加器中的每个项。如果这个角色 同等 ,复制所有以前的组合并添加另一组组合 equiv[<character>]

    const equiv = {
      "a": "4",
      "b": "8",
      "e": "3",
      "i": "1",
      "l": "1",
      "o": "0",
      "t": "7"
    }
    
    const input = "tomato";
    
    const output = [...input].reduce((acc, c, i) => {
      const r = equiv[c];
      
      if (i === 0) {
        return r ? [c, r] : [c];
      }
    
      const updated = acc.map(a => a + c);
      const newItems = r ? acc.map(a => a + r) : [];
      
      return [...updated, ...newItems]
    }, [])
    
    console.log(output)
        4
  •  2
  •   Shidersz    7 年前

    character 以及 replacement 连接到所有以前的结果,生成一组新的结果,否则只有 连接到所有以前的结果。注意,我在这种方法中滥用了spread运算符。

    var equiv = {a: "4", b: "8", e: "3", i: "1", l: "1", o: "0", t: "7"};
    
    const genComb = (str, arr) =>
    {
        if (!str) return arr; // Finish condition.
        let c = str[0];       // New char to be appended.
        let r = equiv[c];     // New char replacement.
    
        return genComb(
            str.slice(1),
            [...arr.map(e => e + c), ...(r ? arr.map(e => e + r) : [])]
        );
    };
    
    String.prototype.l33tCombinations = function()
    {
       return genComb(this, [""], 0);
    }
    
    console.log("tomato".l33tCombinations());
        5
  •  1
  •   Nick    7 年前

    toReturn 一定要搜索每个生词!

    var equiv = {
      "a": "4",
      "b": "8",
      "e": "3",
      "i": "1",
      "l": "1",
      "o": "0",
      "t": "7"
    }
    
    String.prototype.l33tCombinations = function() {
      var toReturn = [this.toLowerCase()];
    
      for (let i = 0; i < toReturn.length; i++) {
      
        for (let j = 0; j < toReturn[i].length; j++) {
          if (equiv[toReturn[i][j]]) {
           let newWord = toReturn[i].split('');
           newWord[j] = equiv[newWord[j]];
           let newWordJoined = newWord.join('');
           if (!toReturn.includes(newWordJoined))
            toReturn.push(newWordJoined);
          }
        }
     
      }
    
      return toReturn;
    }
    
    console.log('tomato'.l33tCombinations());