英文:
how to find max min from nested typed object array using RxJS?
问题
以下是已翻译的代码部分:
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
}
]
},
// ... (其他数据行)
];
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;
}
请注意,这些函数可能不会立即返回最大和最小值,因为它们使用RxJS进行异步操作。如果您在这些函数之后执行其他操作,应该等待它们的异步操作完成,或者可以将操作移到subscribe回调函数内部以确保在获取最大和最小值之后再进行操作。
英文:
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.
答案1
得分: 1
以下是您要翻译的内容:
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 than b
, positive if a
is greater than b
, 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:
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;
}```
<details>
<summary>英文:</summary>
The functions given to min and max should behave like the comparator function passed to [Array.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#syntax):
>The return value should be a number whose sign indicates the relative order of the two elements: negative if `a` is less than `b`, positive if `a` is greater than `b`, and zero if they are equal.
Unfortunately, the documentation of RxJS provides this only through examples, i.e. for [`min()`](https://rxjs.dev/api/index/function/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;
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论