How to do Nested For Loops in Functional Style

你。 提交于 2019-12-22 10:16:50

问题


I'm in the process of learning functional programming, and completely getting rid of for loops has been a challenge sometimes, because they provide so much control and freedom. Below is an example of checking if a string is an isogram or not (no letters should be repeated). With nested for loops, it became an easy solution. Is there a way to do this the functional way with any high order functions or anything else? Any suggestion would be a huge help.

Code:

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

回答1:


You can use every or some together with a suitable string function:

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

Instead of includes you might also have utilised indexOf.




回答2:


You can sort the String first and then apply every on it. It will stop the iteration as soon as two successive letters are the same:

Here is an improved implementation. Credit goes to @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") );

The implementation uses Array.prototype.every's second parameter, which represents the index of the current element (of the iteration). Please note that isIsogram solely depends on functions and their arguments.




回答3:


Another example, like @Bergi but using some ES6 features for comparison.

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

How your ES3 style code could have looked (noting some of the issues pointed out in the comments)

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


来源:https://stackoverflow.com/questions/39434953/how-to-do-nested-for-loops-in-functional-style

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!