使用reduce重构功能-javascript

时间:2018-11-13 05:47:26

标签: javascript

我编写了一个函数,可以将“ aaazeeeee”之类的字符串转换为“ aaa z eeeee”的新字符串

这是我尝试过的有效的代码

const groupCharacters = signature => {
  let newSignature = "", arr = [];

  let result = [...signature].reduce((accumulator, element, index) => {
    // check if last element in accumulator matches current element
    if (accumulator[accumulator.length -1] !== element) {
      // push accumulator into array
      arr.push(accumulator);
      // set newSignature as new element
      newSignature = element;
    } else {
      // else add element to newSignature
      newSignature = accumulator += element;
    }
    
    // if is last item, push to array
    if (index === signature.length - 1) arr.push(element);

    return newSignature;
  })

  return arr;
}

console.log(groupCharacters('aabaaaaa'));

我该如何重构它以便不需要新的字符串或数组?我已经尝试过

const groupCharacters = str => [...str].reduce((accumulator, element) => accumulator[accumulator.length - 1] !== element ? `${accumulator} ` : accumulator + element)

它输出'aaa'

我该如何解决它或使用诸如map之类的东西?

2 个答案:

答案 0 :(得分:5)

要更改您的现有代码但仍使用reduce,我建议reduce放入 string 而不是array:on每次迭代都与当前字符连接,如果下一个字符既已定义且又不等于当前字符,则还与空格连接:

const groupCharacters = str => (
  [...str].reduce((a, char, i) => a + char + (
    str[i + 1] === char || str[i + 1] === undefined
    ? ''
    : ' '
  ), '')
);

console.log(groupCharacters('aaazeeeee'));

或者,您可以使用一个简单的正则表达式-在一个组中捕获一个单词字符,然后尽可能多地向后引用该组,并替换为整个匹配项和一个空格:

const groupCharacters = signature => signature.replace(/(\w)\1*(?!\1|$)/g, '$& ');
console.log(groupCharacters('aaazeeeee'));

要分解它:

  • (\w)-匹配任何单词字符,将其捕获在第一组中(以便以后可以使用\1进行反向引用)

  • \1*-贪婪地重复刚刚匹配零次或多次(尽可能重复)的字符

  • (?!\1|$)-检查刚刚匹配的子字符串是否不跟在字符串的末尾或另一个相同字符的后面。这样可以确保最终重复的子字符串也不会附加空格(也就是说,您不希望'aaa z eeeee ')。

请注意,正则表达式\G(\w)\1*+(?!$)将完成相同的操作,更易于阅读,并且效率更高(\G匹配最后一个匹配项的末尾或匹配项的开头字符串,而+中的\1*+重复 possessive ,这意味着在最后一个子字符串上,引擎将无法回溯,因此一旦将检查最终的完整子字符串,而不是先遍历每个字符)。但是,不幸的是,本机JS不支持所有格量​​词,也不支持\G锚点。

答案 1 :(得分:1)

我将使用reduce来实现此目的,因为OP想要对 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { ViewState["i"] = 1; } } protected void Button1_Click(object sender, EventArgs e) { int i = (int)ViewState["i"]; Button MyButton = new Button(); MyButton.ID = "MyButton" + i; divContainer.Controls.Add(MyButton); i++; ViewState["i"] = i; } 进行操作:-

reduce

它如何工作?

累加器是一个具有键function myFunc(str) { return str.split('').reduce(function (acc, cv, ci) { if (acc.lastElem != cv) { acc.str += (acc.lastElem == "") ? cv : ' ' + cv; } else { acc.str += cv; } acc.lastElem = cv; return acc; }, { lastElem: '', str: '' }).str; } console.log(myFunc('aaabbbcc')); console.log(myFunc('aaazeeeee'))(当前元素之前的元素)和lastElem(字符串形成)的对象。