2

I have an array of words consisting of 2, 3, 4, 5 and so on letter words. im using an ng-For to iterate through the array and ng-if to display the words according to the amount of letters but i cant seem to get a title in to separate them

expected outcome

2 letter words to am as .......

3 letter words the bee sin .......

and so on,

this is what i have so far

<div *ngIf="data">
  <h2 class="title">{{data.letters}}</h2>
  <ul class="wordList" *ngFor="let item of data.word">
      <li *ngIf="item.length ==2">{{item}}</li>
      <li *ngIf="item.length ==3">{{item}}</li>
      <li *ngIf="item.length ==4">{{item}}</li>
      <li *ngIf="item.length ==5">{{item}}</li>
      <li *ngIf="item.length ==6">{{item}}</li>
      <li *ngIf="item.length ==7">{{item}}</li>
      <li *ngIf="item.length ==8">{{item}}</li>
      <li *ngIf="item.length ==9">{{item}}</li>
      <li *ngIf="item.length ==10">{{item}}</li>
      <li *ngIf="item.length ==11">{{item}}</li>
      <li *ngIf="item.length ==12">{{item}}</li>
      <li *ngIf="item.length ==13">{{item}}</li>
      <li *ngIf="item.length ==14">{{item}}</li>

    </ul>
</div>

i know i should also be using an index to iterate through the sized words, ill get to that after :)

Nicholas K
  • 15,148
  • 7
  • 31
  • 57
Peter Snee
  • 15
  • 3
  • Did any answer work for you? If yes please do consider accepting/upvoting them. [What should I do when someone answers my question](https://stackoverflow.com/help/someone-answers) – Nicholas K Feb 15 '21 at 09:59

2 Answers2

1

Make use of a Pipe to transform the array of words into an object whose key is the length of the word and whose values are the words themselves.

@Pipe({ name: 'groupByWordsPipe' })
export class GroupByWordsPipe implements PipeTransform {

    transform(input: []) {
        let map = {};
        input.forEach((e: string) => {
            if (map[e.length]) {
                map[e.length] = map[e.length] + ' ' + e;
            } else {
                map[e.length] = e;
            }
        });
        return map;
    }

}

Now you can easily use this on your template with the following syntax:

<div *ngFor="let word of words | groupByWordsPipe | keyvalue">
    <h2>{{word.key}}</h2> letter words : {{word.value}}
</div>
Nicholas K
  • 15,148
  • 7
  • 31
  • 57
0

I think you will have to handle the grouping by length part in your class and build a suitable object structure to contain the data you want to display. Also notice that since you have a list of groups by word length and a list of words for each one of them you will actually need two nested *ngFor declarations.

In your class:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  private words = ['the', 'to', 'am', 'as', 'bee', 'sin', 'other'];
  groupedByLength: { length: string, words: string[] }[] = [];

  ngOnInit() {
    this.groupByLength();
  }

  private groupByLength() {
    let grouped = {};
    for(let word of this.words) {
      const length = word.length;
      if(!grouped[length]) {
        grouped[length] = [word];
      } else {
        grouped[length].push(word);
      }
    }
    Object.keys(grouped).forEach(key => {
      this.groupedByLength.push({ length: key, words: grouped[key] });
    });
  }
}

In your template:

<div *ngFor="let data of groupedByLength">
    <h2>{{ data.length }} letter words:</h2>
    <ul>
        <li *ngFor="let word of data.words">{{ word }}</li>
    </ul>
</div>
Omar
  • 1,005
  • 11
  • 11