Reputation: 2325
I have this data set
var records = [{
gc: '2',
time: 1231232423,
cards: [{
cardCode: '12121',
rssi: 23
}, {
cardCode: '12122',
rssi: 33
}, {
cardCode: '12421',
rssi: 43
}
]
},
{
gc: '3',
time: 4331232233,
cards: [{
cardCode: '6423',
rssi: 23
}, {
cardCode: '12421',
rssi: 13
}
]
}, , {
gc: '4',
time: 4331232233,
cards: [{
cardCode: '8524',
rssi: 03
},
{
cardCode: '6423',
rssi: 23
}, {
cardCode: '12421',
rssi: 67
}
]
}
]
I have an array(records)
of objects and in each object there is an another array(cards)
. This means if i will always have cards
array inside an object present in 'records'. So from very first i want to iterate over whole list records
and compare the cards array of all objects with each other and then find the matched object's rssi
value and push the object(that have minimum rssi value ) into another new array. In the same way at the end i want the array in which i have all the matching objects which have minimum rssi value. I am using lodash
and have tried this
matchedRecords = records.forEach(record=>{
record.cards.forEach(record=>{
_.filter(records, _.flow(
_.property('cards'),
_.partialRight(_.some, { cardCode: record.cardCode })
));
})
})
My desired result would be
[
{
gc : 3,
cards : [{
cardCode : '12421',
rssi : 13
}]
}
]
Note : cards array object should be compare on the bassis of cardCode key
Upvotes: 0
Views: 84
Reputation: 50787
This version is based on the understanding reached after the long requirements discussion in the comments to the question. It does not use lodash. It's gotten complex enough that it probably should break into smaller pieces, and lodash might help with that.
It includes not just gc
, but also time
from the original records, and will, in fact, include anything else from there. If you want just gc
, simply remove ...rest
from the code.
const sharedCards = records =>
Object.values(
Object .entries (records .reduce (
(a, {cards, ...rest}) => cards .reduce (
(a, {cardCode, rssi}) => ({
...a,
[cardCode]: [...(a[cardCode] || []), {...rest, rssi}]
}),
a,
),
{}
))
.filter ( ([code, rs]) => rs.length == records.length )
.reduce((a, [code, rs]) => {
const {gc, rssi, ...rest} = rs.reduce(
(r1, r2) => r2.rssi < r1.rssi ? r2 : r1,
{rssi: Infinity}
)
return {
...a,
[gc]: {
...(a[gc] || {...rest, gc}),
cards: [...((a[gc] || {gc}).cards || []), {cardCode: code, rssi}]
}
}
}, {})
)
const records = [{gc: "2", time: 1231232423, cards: [{cardCode: "12121", rssi: 23}, {cardCode: "12122", rssi:33}, {cardCode: "12421", rssi: 43}]}, {gc: "3", time: 4331232233, cards: [{cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 13}]}, {gc: "4", time: 4331232233, cards: [{cardCode: "8524", rssi: 3}, {cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 67}]}];
console .log (
sharedCards (records)
)
// Now we add `{cardCode: "6423", rssi: 7}` to the first record
const records2 = [{gc: "2", time: 1231232423, cards: [{cardCode: "6423", rssi: 7}, {cardCode: "12121", rssi: 23}, {cardCode: "12122", rssi:33}, {cardCode: "12421", rssi: 43}]}, {gc: "3", time: 4331232233, cards: [{cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 13}]}, {gc: "4", time: 4331232233, cards: [{cardCode: "8524", rssi: 3}, {cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 67}]}];
console .log (
sharedCards (records2)
)
This is only a partial solution, to be updated if we can resolve the discussion in the comments. It fetches all the cards which appear in every record, and chooses the version with the lowest rssi. This may be close to the requirements, or it may not.
It doesn't use lodash. It might simplify a bit with lodash, but probably not very much.
const sharedCards = records =>
Object .entries (records .reduce (
(a, {cards}) => cards .reduce (
(a, {cardCode, rssi}) => ({...a, [cardCode]: [...(a[cardCode] || []), rssi]}),
a,
),
{}
))
.filter ( ([code, rssis]) => rssis.length == records.length )
.map ( ([code, rssis]) => ({ cardCode: code, rssi: Math .min (...rssis) }) )
const records = [{gc: "2", time: 1231232423, cards: [{cardCode: "12121", rssi: 23}, {cardCode: "12122", rssi:33}, {cardCode: "12421", rssi: 43}]}, {gc: "3", time: 4331232233, cards: [{cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 13}]}, {gc: "4", time: 4331232233, cards: [{cardCode: "8524", rssi: 3}, {cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 67}]}];
console .log (
sharedCards (records)
)
// Now we add `{cardCode: "6423", rssi: 7}` to the first record
const records2 = [{gc: "2", time: 1231232423, cards: [{cardCode: "6423", rssi: 7}, {cardCode: "12121", rssi: 23}, {cardCode: "12122", rssi:33}, {cardCode: "12421", rssi: 43}]}, {gc: "3", time: 4331232233, cards: [{cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 13}]}, {gc: "4", time: 4331232233, cards: [{cardCode: "8524", rssi: 3}, {cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 67}]}];
console .log (
sharedCards (records2)
)
Upvotes: 1
Reputation: 20039
With Lodash
let records = [{"gc":"2","time":1231232423,"cards":[{"cardCode":"12121","rssi":23},{"cardCode":"12122","rssi":33},{"cardCode":"12421","rssi":43}]},{"gc":"3","time":4331232233,"cards":[{"cardCode":"6423","rssi":23},{"cardCode":"12421","rssi":13}]},{"gc":"4","time":4331232233,"cards":[{"cardCode":"8524","rssi":3},{"cardCode":"6423","rssi":23},{"cardCode":"12421","rssi":67}]}]
let mapped = _.reduce(records, (acc, rec) => {
_.forEach(rec.cards, (card) => {
card = _.assign({}, card, { gc: rec.gc, multiple: false })
if (card.cardCode in acc) {
let lc = acc[card.cardCode].rssi < card.rssi
acc[card.cardCode] = lc ? acc[card.cardCode] : card
acc[card.cardCode].multiple = lc
} else {
acc[card.cardCode] = card;
}
})
return acc
}, {})
let result = _.reduce(records, (acc, rec) => {
rec.cards = _.filter(rec.cards, (card) => mapped[card.cardCode].multiple && mapped[card.cardCode].gc === rec.gc )
rec.cards.length && acc.push(rec)
return acc
}, []);
console.log(result)
.as-console-wrapper {
max-height: 100%!important
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Upvotes: 0