Search code examples
javascriptarraystypescriptnested-loops

Nested looping in typescript


I have problems with looping through nested array in a function returning a statement.

  selectInputFilter(enteredText, filter) {
    if (this.searchType === 3) {
      return (enteredText['actors'][0]['surname'].toLocaleLowerCase().indexOf(filter) !== -1);
    } 
  }

So basically instead of manually pointing to [0] element of [actors] i'd like to loop through all elements of array at point. However i do not know how to embedd a loop inside such a returning function. I tried forEach but my VSCode is throwing errors.

The full pipe i need nesting for is below.So basically i cannot include loop in the last else statement. And above all the code looks a lil bit spaghetti like at this point so any recommendations to simplify would be welcome.

export class InputFilterPipe implements PipeTransform{

  searchType: number;
  private subscription: Subscription;

  constructor(private movieService: MovieService) {
    this.movieService.getSearchType().subscribe(
      id => this.searchType = id
    );
  }


      transform(value: any[], filter: string): any[] {
        filter = filter ? filter.toLocaleLowerCase() : null;
        return filter ? value.filter(
          (arraySearched) =>
            this.selectInputFilter(arraySearched, filter))
             : value;
      }

      selectInputFilter(arraySearched, filter) {
        if (this.searchType === 3) {
          const values = [];
          for (let actor of arraySearched['actors']) {
           values.push(actor['surname'].toLocaleLowerCase().indexOf(filter) !== -1);
            for (let i = 0; i < values.length; i++ ) {
              if (values[i] === true) {
                return (arraySearched['actors'][i]['surname'].toLocaleLowerCase().indexOf(filter) !== -1);
              }
            }
          }
      } else if (this.searchType === 2) {
          return (arraySearched['director'].toLocaleLowerCase().indexOf(filter) !== -1);
        } else if (this.searchType === 1) {
          return (arraySearched['title'].toLocaleLowerCase().indexOf(filter) !== -1);
        } else {
          return  (arraySearched['title'].toLocaleLowerCase().indexOf(filter) !== -1) ||
          (arraySearched['director'].toLocaleLowerCase().indexOf(filter) !== -1) ||
            (arraySearched['actors'][0]['surname'].toLocaleLowerCase().indexOf(filter) !== -1) ||
            (arraySearched['actors'][1]['surname'].toLocaleLowerCase().indexOf(filter) !== -1) || 
            (arraySearched['actors'][2]['surname'].toLocaleLowerCase().indexOf(filter) !== -1);
            // (arraySearched['actors'][3]['surname'].toLocaleLowerCase().indexOf(filter) !== -1);
      }
    }

Solution

  • You could make a generator function, like this:

    function* selectInputFilter(enteredText, filter) {
      if (this.searchType === 3) {
        for (var actor of enteredText['actors']) {
          yield actor['surname'].toLocaleLowerCase().indexOf(filter) !== -1;
        }
      }
    }
    

    And use it something like this:

    for (var x of selectInputFilter(/*your args here*/)) {
      // x will loop over each of the "returned" values
    }
    

    Alternatively, you could make and return an array of the desired values, like this:

    function selectInputFilter(enteredText, filter) {
      if (this.searchType === 3) {
        var values = [];
        for (var actor of enteredText['actors']) {
          values.push(actor['surname'].toLocaleLowerCase().indexOf(filter) !== -1);
        }
        return values;
      }
    }
    

    EDIT:

    For that later case, you can use Array.prototype.some, like so

    } else {
      return (arraySearched['title'].toLocaleLowerCase().indexOf(filter) !== -1) ||
          (arraySearched['director'].toLocaleLowerCase().indexOf(filter) !== -1) ||
          (arraySearched['actors'].some((actor) => actor['surname'].toLocaleLowerCase().indexOf(filter) !== -1));
    }
    

    Or just use a variable like this:

    } else {
      let returnValue = (arraySearched['title'].toLocaleLowerCase().indexOf(filter) !== -1) ||
          (arraySearched['director'].toLocaleLowerCase().indexOf(filter) !== -1);
      for (let actor of arraySearched['actors']) {
        if (returnValue) break; // so it doesn't keep looping after returnValue is true
        returnValue = returnValue || actor['surname'].toLocaleLowerCase().indexOf(filter) !== -1);
      }
      return returnValue;
    }