Home > Blockchain >  RXJS data manipulation
RXJS data manipulation

Time:05-07

I am trying to find the reactive way of manipulating data in an array of objects. In the array below, I want to determine the low score in groups of four and add a low and diff property to the item.

arr = [
    { name: 'Cliff', score: 44 },
    { name: 'Bob', score: 55 },
    { name: 'Jack', score: 404 },
    { name: 'John', score: 50 },
    { name: 'Doug', score: 22 },
    { name: 'EZ', score: 550 },
    { name: 'Bill', score: 404 },
    { name: 'Dan', score: 5 },
    { name: 'Rich', score: 404 },
    { name: 'Steve', score: 565 },
  ];
  arr$: Observable<Arr[]> = of(this.arr);

  getData() {
    const scores = this.arr$.pipe(
      map((result) =>
        result.map((data) => {
          return {
            x: data.score,
          };
        })
      )
      // reduce((acc, x) => (acc = acc > x.score ? acc :x.score), 0)
    );

    return scores;
  }
}

/*
Desired result
arr = [
  { name: 'Cliff', score: 44, low: 44, diff 0 },
  { name: 'Bob', score: 55, low: 44, diff: 9 },
  { name: 'Jack', score: 404, low 44, diff: 360 },
  { name: 'John', score: 50, low: 44, diff: 6 },
  { name: 'Doug', score: 22, low 5, diff: 17 },
  { name: 'EZ', score: 550, low 5, diff: 545 },
  { name: 'Bill', score: 404, low 5, diff: 399 },
  { name: 'Dan', score: 5, low 5, diff: 0 },
  { name: 'Rich', score: 404, low: 404, diff: 0 },
  { name: 'Steve', score: 565. low 404, diff: 121 },
];
*/

I can't seem to get past the few lines of code that I've written. A StackBlitz is here.

CodePudding user response:

This could be a reactive way to get what you want. The comments in the code explain the logic.

// the from rxjs function takes an array and returns an 
// Observable that emits each item in the array
from(arr)
  .pipe(
    // bufferCount will emit an array of arrays of items,
    // therefore creates the groups of four items
    bufferCount(4),
    // for each group we find the low and create 
    // the new items with the low value and the diff
    map((buff) => {
      const low = buff.reduce((acc, curr) => {
        return acc < curr.score ? acc : curr.score;
      }, Infinity);
      return buff.map((v) => ({ ...v, low, diff: v.score - low }));
    }),
    // with mergeMap we flatten the groups of items 
    // and emit each item
    mergeMap((buffEnriched) => buffEnriched),
   // if you want to emit an array rather than each single
   // object you add toArray
   toArray()
  )

CodePudding user response:

it makes more sense to sort, then generate your data. otherwise, your output data in your question makes little sense to me.

// DATA IN
arr = [
    { name: 'Cliff', score: 44 },
    { name: 'Bob', score: 55 },
    { name: 'Jack', score: 404 },
    { name: 'John', score: 50 },
    { name: 'Doug', score: 22 },
    { name: 'EZ', score: 550 },
    { name: 'Bill', score: 404 },
    { name: 'Dan', score: 5 },
    { name: 'Rich', score: 404 },
    { name: 'Steve', score: 565 },
  ];
 
// PROCESSING and OUTPUT
let lowest = arr[0].score;
let output_arr = arr.sort((a, b)=>{
    if(a.score < b.score) return -1;
    if(a.score > b.score) return 1;
  return 0;
}).map((a)=>{
    if(a.score < lowest) lowest = a.score;
        return {
        name: 'Steve',
      score: 565,
      low: lowest,
      diff: a.score - lowest
     };
});

// use output array output
console.log(output_arr);

DEMO

Example

INPUT

[
    { name: 'Cliff', score: 44 },
    { name: 'Bob', score: 55 },
    { name: 'Jack', score: 404 },
    { name: 'John', score: 50 },
    { name: 'Doug', score: 22 },
    { name: 'EZ', score: 550 },
    { name: 'Bill', score: 404 },
    { name: 'Dan', score: 5 },
    { name: 'Rich', score: 404 },
    { name: 'Steve', score: 565 },
  ]

OUTPUT

[{
  diff: 0,
  low: 5,
  name: "Steve",
  score: 565
}, {
  diff: 17,
  low: 5,
  name: "Steve",
  score: 565
}, {
  diff: 39,
  low: 5,
  name: "Steve",
  score: 565
}, {
  diff: 45,
  low: 5,
  name: "Steve",
  score: 565
}, {
  diff: 50,
  low: 5,
  name: "Steve",
  score: 565
}, {
  diff: 399,
  low: 5,
  name: "Steve",
  score: 565
}, {
  diff: 399,
  low: 5,
  name: "Steve",
  score: 565
}, {
  diff: 399,
  low: 5,
  name: "Steve",
  score: 565
}, {
  diff: 545,
  low: 5,
  name: "Steve",
  score: 565
}, {
  diff: 560,
  low: 5,
  name: "Steve",
  score: 565
}]
  • Related