So i'm getting this pretty complex array from an API with lots of nested arrays with objects etc. It looks like this:
public data: any[] = [
{
language: 'Dutch',
sources: [
{
source: 'De Redactie',
channels: [
{ channel: 'binnenland', value: false },
{ channel: 'buitenland', value: false },
{ channel: 'sport', value: false },
{ channel: 'cultuur en media', value: false },
{ channel: 'politiek', value: false },
{ channel: 'financien', value: false }
]
},
{
source: 'Tweakers',
channels: [
{ channel: 'hardware', value: false },
{ channel: 'software', value: false },
{ channel: 'tech', value: false },
{ channel: 'smartphones', value: false },
{ channel: 'audio', value: false },
{ channel: 'video', value: false }
]
}
]
},
{
language: 'English',
sources: [
{
source: 'BBC',
channels: [
{ channel: 'news', value: false },
{ channel: 'sport', value: false },
{ channel: 'weather', value: false },
{ channel: 'travel', value: false },
{ channel: 'politics', value: false }
]
},
{
source: 'Fox News',
channels: [
{ channel: 'u.s.', value: false },
{ channel: 'world', value: false },
{ channel: 'opinion', value: false },
{ channel: 'politics', value: false },
{ channel: 'entertainment', value: false },
{ channel: 'business', value: false }
]
}
]
}
]
And i can extract the value that i want (the channel property) with this function:
setChannel(channel: string, source: string, language: string) {
for (const i of this.data) {
if (i.language === language) {
for (const j of i.sources) {
if (j.source === source) {
for (const k of j.channels) {
if (k.channel === channel) {
console.log(k.channel);
}
}
}
}
}
}
}
Now i'm sure that there is a function in lodash to simplify this. Because triple nested for's and if's is not a nice way of coding. But i can't seem to find it in the documentation. Could someone please point me in the right direction?
Lodash's filter()
and flatMap()
will get you there:
const result = _(data).filter({language: 'Dutch'})
.flatMap('sources')
.filter({source: 'De Redactie'})
.flatMap('channels')
.find({channel: 'sport'});
const data = [
{
language: 'Dutch',
sources: [
{
source: 'De Redactie',
channels: [
{ channel: 'binnenland', value: false },
{ channel: 'buitenland', value: false },
{ channel: 'sport', value: false },
{ channel: 'cultuur en media', value: false },
{ channel: 'politiek', value: false },
{ channel: 'financien', value: false }
]
},
{
source: 'Tweakers',
channels: [
{ channel: 'hardware', value: false },
{ channel: 'software', value: false },
{ channel: 'tech', value: false },
{ channel: 'smartphones', value: false },
{ channel: 'audio', value: false },
{ channel: 'video', value: false }
]
}
]
},
{
language: 'English',
sources: [
{
source: 'BBC',
channels: [
{ channel: 'news', value: false },
{ channel: 'sport', value: false },
{ channel: 'weather', value: false },
{ channel: 'travel', value: false },
{ channel: 'politics', value: false }
]
},
{
source: 'Fox News',
channels: [
{ channel: 'u.s.', value: false },
{ channel: 'world', value: false },
{ channel: 'opinion', value: false },
{ channel: 'politics', value: false },
{ channel: 'entertainment', value: false },
{ channel: 'business', value: false }
]
}
]
}
]
const result = _(data).filter({language: 'Dutch'})
.flatMap('sources')
.filter({source: 'De Redactie'})
.flatMap('channels')
.filter({channel: 'sport'})
.first();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
That's actually a pretty "quick & dirty" solution, because I didn't use any fallback default values. But you can read the docs about .find and .get.
const data = [{
language: 'Dutch',
sources: [{
source: 'De Redactie',
channels: [{
channel: 'binnenland',
value: false
},
{
channel: 'buitenland',
value: false
},
{
channel: 'sport',
value: false
},
{
channel: 'cultuur en media',
value: false
},
{
channel: 'politiek',
value: false
},
{
channel: 'financien',
value: false
}
]
},
{
source: 'Tweakers',
channels: [{
channel: 'hardware',
value: false
},
{
channel: 'software',
value: false
},
{
channel: 'tech',
value: false
},
{
channel: 'smartphones',
value: false
},
{
channel: 'audio',
value: false
},
{
channel: 'video',
value: false
}
]
}
]
},
{
language: 'English',
sources: [{
source: 'BBC',
channels: [{
channel: 'news',
value: false
},
{
channel: 'sport',
value: false
},
{
channel: 'weather',
value: false
},
{
channel: 'travel',
value: false
},
{
channel: 'politics',
value: false
}
]
},
{
source: 'Fox News',
channels: [{
channel: 'u.s.',
value: false
},
{
channel: 'world',
value: false
},
{
channel: 'opinion',
value: false
},
{
channel: 'politics',
value: false
},
{
channel: 'entertainment',
value: false
},
{
channel: 'business',
value: false
}
]
}
]
}
];
const setChannel = (channel = '', source = '', language = '') => {
// get all sources for the given language
const sourcesForLanguage = _.get(_.find(data, ['language', language]), 'sources');
// get all channels for given source
const channelsForSource = _.get(_.find(sourcesForLanguage, ['source', source]), 'channels');
// get the channel object for given channel
const selectedChannel = _.find(channelsForSource, ['channel', channel]);
console.log(selectedChannel);
}
setChannel('news', 'BBC', 'English');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With