Javascript 比较父字段和子字段';筛选后数组中的值

Javascript 比较父字段和子字段';筛选后数组中的值,javascript,typescript,rxjs,Javascript,Typescript,Rxjs,我有以下父母和子女: 我需要过滤父项,其中有子项,且id等于6: { id: 2, type: 'B', children: [{ id: 5, type: 'D' }, { id: 6, type: 'B' }] } 为此,我使用了RxJs操作符: parents.pipe( flatMap(parents => parents), map(parent => parent.children.find(child => child.id == 6)) ).subsc

我有以下
父母
子女

我需要过滤
父项
,其中有
子项
,且
id
等于6:

{ id: 2, type: 'B', children: [{ id: 5, type: 'D' }, { id: 6, type: 'B' }] }
为此,我使用了RxJs操作符:

parents.pipe(
  flatMap(parents => parents),
  map(parent => parent.children.find(child => child.id == 6))
).subscribe(x => console.log(x));
输出为以下
子项

{id: 6, type: "B"}
但是我需要得到一个可观察的
值,如果:

parent.type == child.type (In this case it would be true, e.g., 'B' == 'B')
我一直在尝试
FlatMap
Reduce
Filter
Find

但我永远无法得到
父类
,因此我可以比较
父类
子类
类型

{ id: 2, type: 'B', child: { id: 6, type: 'B' } }

如果替换此项:
parent.children.find(child=>child.id==6)
使用
parent.find(p=>p.children.some(c=>c.id==6))
然后不是接收
{id:6,而是键入:“B”}
您将接收包含所有子级的父级

如果只想设置id为6的子级,可以使用编辑行
映射(parent=>parent.children.find(child=>child.id==6))

 map(parent => {
   parent.child = parent.children.find(c => c.id === 6);
   return parent;
 })

在此之后,您将获得包含id为6的子级的附加属性child(parent.child)的父级,而不是接收
{id:6,输入:“B”}
。然后您可以检查parent.type===parent.child.type。请注意,parent.child可能未定义,因此需要添加额外的检查。

如果您的方法正确,只需将您的可观察对象映射到布尔值,即检查您的子类型是否等于父类型,我们可以重用您当前的
映射
,并使其返回布尔值而不是子类型。我们这样做是因为我们同时需要父母和孩子

parents.pipe(
  flatMap(parents => parents),
  map(parent =>  {
    // we get the child with id 6
    let child = parent.children.find(child => child.id == 6)
    // we check if the child exists ( in the first case it does not )
    // we check if the parent type is equals to the child type.
    return child && parent.type === child.type;
  }),
).subscribe(x => console.log(x) /* true or false */);

我已使用此修复程序分叉/编辑了您的代码。

下面的代码经过测试,应该可以工作,如果您需要匹配某些id,可以在
reduce
中添加更多条件

import { from } from 'rxjs';
import {mergeMap,first,reduce,filter,last,defaultIfEmpty} from 'rxjs/operators'

const parents = 
  [
    { id: 1, type: 'A', children: [{ id: 3, type: 'A' }, { id: 4, type: 'C' }] },
    { id: 2, type: 'B', children: [{ id: 5, type: 'D' }, { id: 6, type: 'C' }] }
  ];
from(parents).pipe(
    mergeMap(parent=>from(parent.children).pipe(reduce((acc:any,child)=>{
         console.log(parent.type,child.type)
         if(acc) return acc
         return child.type===parent.type
    },false))),
    filter((bool:any)=>bool),
    defaultIfEmpty(false)
   ).subscribe(console.log)

您是需要为每个父对象指定一个布尔值,还是为整个父对象集指定一个布尔值。如果是这样,那么如果所有父项都具有相同的类型,或者只有一个具有相同的类型,它是否会返回true?它是否需要是rxjs?@nicolas因为id是唯一的,所以只有一个子项的id等于do 6。因此,我只需要该父级和该父级的布尔值。因此,对于所有父级,您只需要一个布尔值,就可以查看是否有一个父级与其子级具有相同的类型?@RenaldoBalaj是的,我更喜欢使用rxjs。您的代码与我要查找的不完全一样。。。使用
find(child=>child.id==6)
时,将只有一个子项,因为所有id都是唯一的,并且一个子项只能属于一个父项。因此,我不希望每个父级返回一个布尔值(true或false)。我希望找到哪个父级具有ID=6的子级,然后在父级类型等于子级类型时返回。并不是所有的父母……我确实像你说的那样得到了父母,但有两个孩子。如何将父对象的类型与Id==6的子对象进行比较?请检查更新后的示例并给出建议:如果使用第一种方法,则需要运行查找;如果运行第二种方法,则可以在
parent.child
下访问该方法。明白了。。。我能够使用第一种方法使用
map(parent=>parent.type===parent.children.find(x=>x.id==6.type)
import { from } from 'rxjs';
import {mergeMap,first,reduce,filter,last,defaultIfEmpty} from 'rxjs/operators'

const parents = 
  [
    { id: 1, type: 'A', children: [{ id: 3, type: 'A' }, { id: 4, type: 'C' }] },
    { id: 2, type: 'B', children: [{ id: 5, type: 'D' }, { id: 6, type: 'C' }] }
  ];
from(parents).pipe(
    mergeMap(parent=>from(parent.children).pipe(reduce((acc:any,child)=>{
         console.log(parent.type,child.type)
         if(acc) return acc
         return child.type===parent.type
    },false))),
    filter((bool:any)=>bool),
    defaultIfEmpty(false)
   ).subscribe(console.log)