简体   繁体   中英

Filter object of object with RxJS

I have the following stream and I would like to filter and keep only the params that are true(boolean).

{
  "colors": {
    "red": "",
    "yellow": true,
    "green": false
  },
  "size": {
    "t5": true,
    "t10": "",
    "t20": true
  }
}

I need the output to look like this:

{
  "colors": ["yellow"],
  "size": ["t5,t20"]
}

Here are my thougt when I try to deal with this:

  • I tried to use map but without success. I guess it's because it's an object and not an array.
  • All keys and values are dynamic in this object so I can't use them to manipulate the object.
  • flatMap() help me a bit but I don't know what to do with it as I don't know the name of the keys.
this.form.valueChanges
  .debounceTime(400)
  .flatMap(x => Object.values(x))
  .subscribe(console.log)

This is not an rxjs issue, just a plain js mapping:

getTruthyKeys(obj: any): Array<string> {
   return Object.keys(obj).filter(key => obj[key] === true);
}

mainKeysToTruthyLists(obj: any): Array<{key: string, truthy: Array<string>}> {
  let result = {};
  Object.keys(obj).forEach(key => result[key] = getTruthyKeys(obj[key]);
  return result;
}

and now you can apply it as a map on your stream:

this.form.valueChanges
  .debounceTime(400)
  .map(mainKeysToTruthyLists)
  .subscribe(console.log)

This isn't really a RxJS question. All that RxJS should do here is map . This can be done with Object.entries :

this.form.valueChanges
.debounceTime(400)
.map(obj => {
  return Object.entries(obj)
  .reduce((newObj, [key, subObj]) => {
    const subArr = Object.entries(subObj)
    .filter(([, subValue]) => subValue)
    .map(([subKey]) => subKey);

    return Object.assign(newObj, { [key]: subArr });
  }, {})
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM