Rxjs array of object distinct with clause - rxjs

I've got these streams
const site = of([
{ name: 'Joe', age: 30, tsUpdate: 5 },
{ name: 'Frank', age: 20, tsUpdate: 4 },
{ name: 'Ryan', age: 50, tsUpdate: 4 }
]);
const db = of([
{ name: 'Jonas', age: 30, tsUpdate: 4 },
{ name: 'Frank', age: 21, tsUpdate: 8 },
{ name: 'Calgor', age: 50, tsUpdate: 4 },
{ name: 'Joe', age: 30, tsUpdate: 4 },
]);
The goal is to have a single array with distinct value for
name but with the highest tsUpdate
So for instance
{ name: 'Joe', age: 30, tsUpdate: 5 }
{ name: 'Joe', age: 30, tsUpdate: 4 }
I want
{ name: 'Joe', age: 30, tsUpdate: 5 }
I am able to have distinct value for name property
but I don't know how to pick the highest value for tsUpdate
https://stackblitz.com/edit/rxjs-mhept2?devtoolsheight=60

This could be a way to solve it:
forkJoin(
[
site,
db
]
).pipe (
map(([site, db]) => [...site, ...db]),
// Emit each item individually
mergeAll(),
// Group by their name
groupBy(o => o.name),
// For each separate group, find the object with the highest `tsUpdate`
mergeMap(
grp$ => grp$.pipe(
reduce((acc, crt) => crt.tsUpdate > acc.tsUpdate ? crt : acc),
),
),
// At the end, collect all the objects in an array
toArray(),
).subscribe(console.log);
A groupBy's group is a Subject, and that's why we can use mergeMap afterwards. That subject will emit whenever it finds an object that matches with its key.
StackBlitz.

Related

elasticsearch 5: returning same document multiple times if multiple array items of one document fit condition

We are using elastic search 5 (yes I know it is EOL but it is what it is)
Elastic newbie here with a rather complicated task:
Let's imagine we have an event index filled with multiple event documents. Those event documents might have n speakers attached in a speakers object array. A speaker has a gender attribute.
How can I achieve the following query?
"return event for each speaker whose gender is x "
returning query result:
{
page: 1,
pageSize: 20,
total: 3
items: [
{
id: 1,
speakers: [
{
name: 'Sascha',
gender: 'x'
}
]
},
{
id: 1,
speakers: [
{
name: 'Leo',
gender: 'x'
}
]
},
{
id: 2,
speakers: [
{
name: 'Rue',
gender: 'x'
}
]
},
]
}
event index filled with three event documents
event 1
{
id: 1,
speakers: [
{
name: 'Sascha',
gender: 'x'
},
{
name: 'Leo',
gender: 'x'
},
]
}
event 2
{
id: 2,
speakers: [
{
name: 'Thomas',
gender: 'm'
},
{
name: 'Rue',
gender: 'x'
},
]
}
event 3
{
id: 2,
speakers: [
{
name: 'Nicole',
gender: 'f'
}
]
}
I didn't even start to code or write a query because I am not sure if elastic is built to give me a result like the one I want to achieve.
I don't even know how to articulate the type of query I am trying to achieve :/
Or do I have to create a new index which combines event and speaker index in a way I can work with?

How do I remove duplicate items from observable array based on multiple properties?

If I have an array of items like
[
{id: 1, name: 'Sam', gender: 'boy'},
{id: 2, name: 'Mary', gender: 'girl'},
{id: 3, name: 'Sam', gender: 'boy'}
]
Matching on just name and gender, how do I reduce it to the following result?
[
{id: 1, name: 'Sam', type: 'boy'},
{id: 2, name: 'Mary', type: 'girl'}
]
Let try
items$.pipe(map(this.uniqueArray))
uniqueArray(array: any[]): any[] {
return array.filter(
(item, index, self) =>
index === self.findIndex((x) => x.name === item.name)
);
}
https://stackblitz.com/edit/angular-isqjpa?file=src/app/hello.component.ts

Normalizing a nested entity that shares the current schema

My goal is to normalize this object:
{
talks: [
{
id: 1755,
speakers: [
{
id: 1487,
name: 'John Doe',
},
],
related_talks: [{
id: 14,
speakers: [{
id: 125,
name: 'Jane Doe',
}],
event: {
id: 181,
name: 'First Annual',
},
}],
event: {
id: 180,
name: 'July Party',
},
},
],
};
into this result:
{
entities: {
events: {
181: {
id: 181,
name: 'First Annual'
},
180: {
id: 180,
name: 'July Party'
}
},
speakers: {
125: {
id: 125,
name: 'Jane Doe'
},
1487: {
id: 1487,
name: 'John Doe'
}
},
talks: {
1755: {
id: 1755,
event: 181,
speakers: [ 1487 ],
related_talks: [ 14 ],
},
14: {
id: 14,
speakers: [ 125 ],
event: 180,
}
},
},
result: {
talks: [ 1755, 14 ],
},
}
If you'll notice, the items in related_talks are treated the same as a talk.
My schemas follow the examples and are set up like this:
const speaker = new schema.Entity('speakers');
const event = new schema.Entity('events');
export const talk = new schema.Entity('talks', {
speakers: [speaker],
event,
});
talk.define({ related_talks: [talk] });
No matter what I try, I can't get the items in related_talks to be added to the result.talks array. It is, however, in the entities object.
What is my schema configuration missing in order to accommodate this?
Unfortunately, if this is your requirement, Normalizr is not for you. Alternatively, if you're looking for a list of "talks" by ID, you can use Object.keys(data.entities.talks)

Lodash filter unique documents

How can I filter the current data:
[{
key: 'T1',
legs:[{ fno: 'W321',date: '2017-01-02 18:20:00.000+0200'}],
fare: { type: 'B', price: 25 }
},{
key: 'T1',
legs:[{ fno: 'W321', date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'E', price: 23 }
},{
key: 'T1',
legs:[{ fno: 'W321', date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'E', price: 20}
}]
I want to group by legs[0].fno, legs[0].date and fare.type, and keep the lowest priced items in each group. This is the expected result:
[{
key: 'T1',
legs:[{ fno: 'W321',date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'B', price: 25}
},{
key: 'T1',
legs:[{ fno: 'W321',date: '2017-01-02T18:20:00.000+0200'}],
fare: { type: 'E', price: 20}
}]
Use _.groupBy() with a callback to create a string to group by, then _.map() each group to a single item using _.minBy():
var data = [{"key":"T1","legs":[{"fno":"W321","date":"2017-01-02 18:20:00.000+0200"}],"fare":{"type":"B","price":25}},{"key":"T1","legs":[{"fno":"W321","date":"2017-01-02T18:20:00.000+0200"}],"fare":{"type":"E","price":23}},{"key":"T1","legs":[{"fno":"W321","date":"2017-01-02T18:20:00.000+0200"}],"fare":{"type":"E","price":20}}];
var result = _(data)
// group by the combined group keys
.groupBy(function(o) {
// extract all group keys and join them to a string
return _.at(o, ['key', 'legs[0].date', 'fare.type']).join('');
})
.map(function(group) {
// get the object object with the minimum fare.price
return _.minBy(group, 'fare.price');
})
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

RethinkDb: Has many query

Have two table, Quiz and Questions
Quiz table store questions id and its display position.
Display position is different for every Quiz.
Quiz table:
{
id: '1'
name: 'Quiz 1'
questions: [
{
question_id: '1',
position: 4
},
{
question_id: '2',
position: 1
},
......
]
}
...
Question Table:
[
{
id: '1',
title: 'Question 1'
},
{
id: '2'
title: 'Question 2'
}
]
I want the the return result like this
{
id: '1',
name: 'Quiz 1',
questions: [
{
position: 4,
title: 'Question 1'
},
{
position: 1,
title: 'Question 2'
}
]
}
How can i get the desired result?
thanks
I got the desired result by using following query
r.db('database').table("quizes").get(id)
.do((quiz) => {
return quiz.merge({'questions': quiz('questions').map((q) => {
return q.merge((r.db('database').table('questions').get(q('id')).without('id')))
})
})
})

Resources