0

I have an Observable anmed "History" in which there is an array of elements. It is represented by this json file : (As you can see there are 3 types of entries just the id changes...)

I would like to create another Observable in which I store each type of entry sorted by the number of times they are present in the json file. With the json file that is above.

How do I go through my "History" Observable and create a sorted "Content" Observable based on the number of times there is each entry in the "History" Observable

Picolo
  • 23
  • 6

2 Answers2

1

Assuming two entries are the same based on the SNS.

First you need to count all the entries, then you can place them in sorted order.

Here is an implementation where original$ is the original observable.

  new$ = original$.pipe(map((res: any) => this.sort(res.history)));

  sort(history: any[]): any[] {
    const result = [];
    const counts: { [key: string]: number } = {};
    for (const i of history) {
      if (counts[i.SNS] === undefined) {
        counts[i.SNS] = 0;
        result.push(this.stripId(i));
      }
      counts[i.SNS]++;
    }
    return result.sort((a, b) => counts[b.SNS] - counts[a.SNS]);
  }

  stripId(object: any) {
    const result = { ...object };
    delete result.id;
    return result;
  }

I use any because I'm too lazy to create types for this example, but you should use actual types.

Stackblitz: https://stackblitz.com/edit/angular-ivy-rqzyx8?file=src/app/app.component.ts

Chris Hamilton
  • 9,252
  • 1
  • 9
  • 26
  • Thank you Chris it worked, I just had to delete the ".history" in "res.history" of this line : new$ = original$.pipe(map((res: any) => this.sort(res.history))); – Picolo Jul 05 '22 at 02:51
  • Hello Chris, I was wondering if you could do the same thing you did for this question but with array.reduce function instead of the sort. Thank you in advance – Picolo Jul 17 '22 at 19:38
0

We could make an function groupBy https://stackoverflow.com/a/21776652/15439733 to group our items by property and use sort to sort arrays by length. https://stackoverflow.com/a/11208371/15439733

html:

<div *ngFor="let group of groupedData">
  <br />
  <br />
  {{ group.length }} items
  <div *ngFor="let item of group">
    <br />
    id: {{ item.id }} SNS:{{ item.SNS }} DMC:{{ item.DMC }} date:{{
      item.date | date: 'short'
    }}
    showTrash: {{ item.showTrash }} points: {{ item.points }}
  </div>
</div>
  groupedData: any;

  ngOnInit(): void {
    of(this.history).subscribe((data) => {
      this.groupedData = groupBy(data, 'title').sort((a, b) => {
        return b.length - a.length;
      });
      console.log(this.groupedData);
    });
  }

  ngOnDestroy() {}
}

export function groupBy(collection, property) {
  let i = 0,
    val,
    index,
    values = [],
    result = [];
  for (; i < collection.length; i++) {
    val = collection[i][property];
    index = values.indexOf(val);
    if (index > -1) result[index].push(collection[i]);
    else {
      values.push(val);
      result.push([collection[i]]);
    }
  }
  return result;
}
0: (3) [{…}, {…}, {…}]
1: (2) [{…}, {…}]
2: (1) [{…}]

json = [
    [
        {
            "id": 3,
            "SNS": "74-10-02 Fuel Metering Unit (FMU)",
            "title": "Chidori Fuel Metering Unit (FMU) - Removal",
            "DMC": "DMC-PW800-A-75-10-17-00A-520A-A",
            "date": "2022-07-02T21:26:42.826Z",
            "showTrash": false,
            "points": 0
        },
        {
            "id": 874119204.715397,
            "SNS": "74-10-02 Fuel Metering Unit (FMU)",
            "title": "Chidori Fuel Metering Unit (FMU) - Removal",
            "DMC": "DMC-PW800-A-75-10-17-00A-520A-A",
            "date": "2022-07-02T21:28:38.116Z",
            "showTrash": false,
            "points": 0
        },
        {
            "id": 221440940.97637305,
            "SNS": "74-10-02 Fuel Metering Unit (FMU)",
            "title": "Chidori Fuel Metering Unit (FMU) - Removal",
            "DMC": "DMC-PW800-A-75-10-17-00A-520A-A",
            "date": "2022-07-02T21:28:38.679Z",
            "showTrash": false,
            "points": 0
        }
    ],
    [
        {
            "id": 2,
            "SNS": "85-05-14 Flange B Bracket Relocation",
            "title": "Mangekyu Conversion - Miscellaneous",
            "DMC": "DMC-PW800-A-72-31-28-00A-910A-B",
            "date": "2022-07-02T21:26:41.098Z",
            "showTrash": false,
            "points": 0
        },
        {
            "id": 653540875.8536806,
            "SNS": "85-05-14 Flange B Bracket Relocation",
            "title": "Mangekyu Conversion - Miscellaneous",
            "DMC": "DMC-PW800-A-72-31-28-00A-910A-B",
            "date": "2022-07-02T21:28:34.530Z",
            "showTrash": false,
            "points": 0
        }
    ],
    [
        {
            "id": 144280205.0483089,
            "SNS": "72-00-10 General",
            "title": "Rasengan Low Pressure Compressor",
            "DMC": "DMC-PW800-A-72-31-25-00A-910A-8",
            "date": "2022-07-02T21:28:32.971Z",
            "showTrash": false,
            "points": 0
        }
    ]
]

for (const group of json) {
console.log(group)
}

Working example: https://stackblitz.com/edit/angular-ivy-vtx8mk?file=src%2Fapp%2Fapp.component.html

Joosep Parts
  • 5,372
  • 2
  • 8
  • 33
  • And from there how do I display each element from the most used to the less used ? – Picolo Jul 03 '22 at 01:41
  • Apply `.sort()` by array length and `*ngFor` over the items. I have added this to the demo. – Joosep Parts Jul 03 '22 at 01:57
  • I have applied to sorting you suggested and it is a good start but I am actually trying to merge all identical items into one element of the array only not just count the occurences. Do you know how to do that ? For example I have 3 items with different ids : I want to display only one element representing all 3 items with no id attribute – Picolo Jul 03 '22 at 23:57
  • Well, sure its possible to group items with same keys and same values, but you just said that id is different for each. So you mean group items with identical keys and values (except id)? – Joosep Parts Jul 04 '22 at 02:36
  • Yes exactly except the id ! – Picolo Jul 04 '22 at 13:03