given I have this
type DataTableType = {
name: string;
series: {
name: string;
value: number;
}[];
}[];
let datatable: DataTableType = [
{
name: 'Row 1',
series: [
{
name:'Series 1',
value:7110
},
{
name:'Series 2',
value:8240
},
{
name:'Series 3',
value:2111
},
{
name:'Series 4',
value:3120
}
]
},
{
name: 'Row 2',
series: [
{
name:'Series 1',
value:6500
},
{
name:'Series 2',
value:9120
},
{
name:'Series 3',
value:5123
},
{
name:'Series 4',
value:8200
}
]
},
{
name: 'Row 3',
series: [
{
name:'Series 1',
value:-6453
},
{
name:'Series 2',
value:-9000
},
{
name:'Series 3',
value:5009
},
{
name:'Series 4',
value:8900
}
]
},
{
name: 'Row 4',
series: [
{
name:'Series 1',
value:8567
},
{
name:'Series 2',
value:4332
},
{
name:'Series 3',
value:-3111
},
{
name:'Series 4',
value:-3222
}
]
},
{
name: 'Row 5',
series: [
{
name:'Series 1',
value:8333
},
{
name:'Series 2',
value:3234
},
{
name:'Series 3',
value:-7323
},
{
name:'Series 4',
value:1544
}
]
},
{
name: 'Row 6',
series: [
{
name:'Series 1',
value:2112
},
{
name:'Series 2',
value:3232
},
{
name:'Series 3',
value:-8231
},
{
name:'Series 4',
value:1111
}
]
},
{
name: 'Row 7',
series: [
{
name:'Series 1',
value:-2112
},
{
name:'Series 2',
value:3232
},
{
name:'Series 3',
value:8231
},
{
name:'Series 4',
value:-9111
}
]
},
{
name: 'Row 8',
series: [
{
name:'Series 1',
value:-2112
},
{
name:'Series 2',
value:100
},
{
name:'Series 3',
value:-3
},
{
name:'Series 4',
value:0
}
]
}
]
I want to find the Max and Min from the datatable with using RxJS, I have done this below to find the Max and Min
function findMax(column: DataTableType) {
let maxN = column[0].series[0].value;
of(...column)
.pipe(
mergeMap(
(item: DataTableType[number], i: number) => from(
[...item.series]
)
.pipe(
max((a, b) => a.value < b.value? b.value : a.value)
)
)
)
.subscribe(
(category: { value: number; }) => {
maxN = category.value;
}
)
;
return maxN;
}
function findMin(column: DataTableType) {
let minN = column[0].series[0].value;
of(...column)
.pipe(
mergeMap(
(item: DataTableType[number], i: number) => from(
[...item.series]
)
.pipe(
min((a, b) => a.value > b.value? b.value : a.value)
)
)
)
.subscribe(
(category: { value: number; }) => {
minN = category.value;
}
)
;
return minN;
}
But whenever I run the functions findMax(datatable) and findMin(datatable) I get max = 0 and min = -2112 of the last element of the object array which is Row 8.
My expected answer should be max = 9120 and min = -9111
Please I need help.
The functions given to min and max should behave like the comparator function passed to Array.sort():
The return value should be a number whose sign indicates the relative order of the two elements: negative if
a
is less thanb
, positive ifa
is greater thanb
, and zero if they are equal.
Unfortunately, the documentation of RxJS provides this only through examples, i.e. for min()
it gives the example:
min((a, b) => a.age < b.age ? -1 : 1)
Note that min
and max
work with the same comparison, you don't have to adjust it depending on whether you want min or max. So in your case, it is (a,b) => a.value - b.value
for both.
A second problem in your functions is that you apply the min
/max
to the steam you generate inside the mergeMap()
, so it will be evaluated for each group, instead of the flattened stream. So you will get a result for every Row
item, and your variable will be set to each of them, until it is returned with the value from the last iteration.
Instead, apply min
/max
after the merge, so that you get the smallest/largest value from the whole stream.
Together with the fixed comparator, this gives you:
function findMax(column) {
let maxN = column[0].series[0].value;
from(column)
.pipe(mergeMap(item => item.series))
.pipe(max((a, b) => a.value - b.value))
.subscribe(
(category) => {
maxN = category.value;
}
)
;
return maxN;
}
Alternatively, you can also have the mergeMap
extract the values directly, then you don't have to use a comparator:
function findMax(column) {
let maxN = column[0].series[0].value;
from(column)
.pipe(mergeMap(item => from(item.series).pipe(map(s => s.value))))
.pipe(max())
.subscribe(
(category) => {
maxN = category;
}
)
;
return maxN;
}