如何以函数式风格做嵌套的 For 循环

How to do Nested For Loops in Functional Style

我正在学习函数式编程,完全摆脱 for 循环有时是一个挑战,因为它们提供了如此多的控制和自由。下面是检查字符串是否为 isogram 的示例(不应重复任何字母)。使用嵌套的 for 循环,它成为一个简单的解决方案。有没有办法用任何高阶函数或其他任何函数来实现这个功能?任何建议都会有很大的帮助。

代码:

function isIsogram(string) {
  let array = string.split('');
  let condition = true;
  for (let i = 0; i < string.length; i++) { //first loop picks character
    for (j = i + 1; j < string.length; j++) { //second loop compares it rest
      if (array[i].toLowerCase() == array[j].toLowerCase())
        condition = false; //if repeat, the condition false
    }
    return condition;
  }
}

您可以将 every or some 与合适的字符串函数一起使用:

function isIsogram(string) {
    string = string.toLowerCase(); // case insensitive
    return string.split('').every(function(character, index) {
        return !string.includes(character, index+1);
    });
}

而不是 includes you might also have utilised indexOf

另一个例子,类似于@Bergi,但使用了一些 ES6 特性进行比较。

function isIsogram(string) {
  string = string.toLowerCase(); // case insensitive
  for (let character of Array.from(string).entries()) {
    if (string.includes(character[1], character[0] + 1)) {
      return false;
    }
  }
  return true;
}

console.log(isIsogram('abc'));
console.log(isIsogram('abca'));

您的 ES3 样式代码看起来如何(注意评论中指出的一些问题)

function isIsogram(string) {
  string = string.toLowerCase(); // case insensitive
  var length = string.length;
  for (var i = 0; i < length; i += 1) {
    for (var j = i + 1; j < length; j += 1) {
      if (string.charAt(i) === string.charAt(j)) {
        return false;
      }
    }
  }
  return true;
}

console.log(isIsogram('abc'));
console.log(isIsogram('abca'));

您可以先对 String 进行排序,然后在其上应用 every。一旦两个连续的字母相同,它就会停止迭代:

这是一个改进的实现。感谢@Xotic750:

function isIsogram(x) {
  return Array.from(x.toLowerCase()).sort().every((y, i, xs) => i === 0 
   ? true
   : y !== xs[i - 1]);
}

console.log( isIsogram("consumptively") );
console.log( isIsogram("javascript") );

该实现使用 Array.prototype.every 的第二个参数,它表示当前元素(迭代的)的索引。请注意 isIsogram 完全取决于函数及其参数。