0

I'm using Angular 14.

I have an Observable that is an Array of Objects, looks like a dictionary with key/values.

Array: [
  0: Object {id: 100, manufacturer: 'ford', model: 'mustang'},
  1: Object {id: 110, manufacturer: 'ford', model: 'fiesta'},
  2: Object {id: 150, manufacturer: 'ford', model: 'escort'},
  3: Object {id: 320, manufacturer: 'Toyota', model: 'camry'},
  4: Object {id: 325, manufacturer: 'Toyota', model: 'rav4'},
  5: Object {id: 345, manufacturer: 'Toyota', model: 'corolla'},

]

I want to group this array by manufacturer. I need two separate lists for Ford and Toyota.

I have read about the RxJs .groupBy() but I can't get it to work as this is a dictionary.

this.cars$.pipe(
        groupBy(g => g[??????].manufacturer),
        mergeMap(group => group.pipe(toArray()))
      ).subscribe(s => { .... });

I have also read about the Javascript reduce() function but it is difficult to understand and I can't find an example of it reducing a dictionary.

Any help appreciated!

3
  • I think the issue is that g in your groupBy is the whole array. groupBy as a pipe operator works on a series of emissions Commented Apr 17, 2023 at 7:44
  • about a reduce, think in this as a "confortable way" to make a loop, see a example in this SO. An example of reduce to group in this another SO Commented Apr 17, 2023 at 7:59
  • Yeah, I don't think groupBy() can do what I want for exactly that (it's a whole array in there). Reduce() was the winner! Commented Apr 18, 2023 at 1:16

1 Answer 1

2

To group your array of objects by manufacturer, you can use the reduce() method to create a new object with keys for each manufacturer and values as arrays of cars.

Here's an example implementation:

this.cars$.pipe(
  map(cars => cars.reduce((acc, car) => {
    if (!acc[car.manufacturer]) {
      acc[car.manufacturer] = [];
    }
    acc[car.manufacturer].push(car);
    return acc;
  }, {})),
).subscribe(manufacturers => {
  const fordCars = manufacturers['ford'];
  const toyotaCars = manufacturers['Toyota'];
  // Do something with the grouped arrays
});

Explanation:

  • map() operator is used to transform the original Observable of cars array into a new Observable that emits an object with manufacturers as keys and arrays of cars as values.
  • reduce() method is used to iterate through each car in the array and add it to the corresponding manufacturer array in the accumulator object.
  • The accumulator object starts as an empty object {}.
  • If the manufacturer array doesn't exist yet, it's initialized with an empty array.
  • The acc (accumulator) object is returned at the end of each iteration, which builds up the final grouped object.
  • The subscribe() method is used to consume the resulting object and extract the arrays for Ford and Toyota, which can be used for further processing.

Hope this helps!

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I'll give it a shot! I didn't try acc[car.manufacturer] I have my fingers and toes crossed for luck :)
Yes this worked! A quick note for others - you need the trailing {} in the reduce statement. It is for setting the initial value. Without it you will get "TypeError: Reduce of empty array with no initial value"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.