问题
I have a service producing objects that are like triples. They will be in this format:
{ country, attribute, value }
Example:
{ country: 'usa', attribute: 'population', value: 100 }
{ country: 'mexico', attribute: 'population', value: 200 }
{ country: 'usa', attribute: 'areaInSqM', value: 3000 }
Ultimately I want to display these as a table. Rows are countries, columns are attributes. So the table would look like:
| country | population | areaInSqM |
| usa | 100 | 3000 |
| mexico | 200 | |
My assumption (possibly wrong) is that I need to create an intermediate data structure that is an array of rows. Such as:
[ { country: 'usa', population: 100, areaInSqM: 3000 }, .... ]
My current solution is a non-RxJS mess of objects where I store a Set containing each attribute type, store a lookup object indexed by country, and convert the lookup object back to the above array at the end. Lots of looping and double storage that I'd prefer to avoid.
Does RxJS have any operators that aid in this type of operation?
Is there a smarter approach?
In this particular case, assumptions are:
- The attributes are not known ahead of time
- The values are always numeric
- A given 'cell' can be null. In this example, mexico areaInSqM is never provided
Edit: Plunkr with solution: https://plnkr.co/edit/FVoeVmmzMN7JGJ3zWFQM?p=preview
回答1:
There are two components in your question, the data structure part, and the data flow part (I suppose you get these data as a stream i.e. one by one, hence the reason why you use Rxjs).
A simple way to iteratively build you data structure is to use the scan operator. For instance :
myDataStructure$ = dataSource$.scan(function (accDataStructure, triple){
accDataStructure[triple.country] = accDataStructure[triple.country] || {}
accDataStructure[triple.country][triple.attribute] = accDataStructure[triple.country][triple.attribute] || {}
accDataStructure[triple.country][triple.attribute] = triple.value
return accDataStructure
}, {})
That makes the assumption that dataSource$ produces objects of the shape { country, attribute, value }. Then myDataStructure$ will output, for every incoming data, the iteratively built data structure that you are seeking. If you only want that data structure once it is finished building, just add a .last() to myDataStructure$.
This is not tested so let me know if that worked
来源:https://stackoverflow.com/questions/43332674/rxjs-to-combine-attributes-from-triples-to-a-table