Reputation: 852
I'm trying to filter one value out of a JSON array that has the highest view_count and has at least 60 seconds. However if the video with the highest view count isn't at least 60 seconds then it returns an undefined.
How do I get the video with the highest viewcount that has at least 60 seconds?
let highest_votes = Math.max.apply(Math, videos_details.map(function (o) { return o.data.view_count; }));
let obj = videos_details.find(function (o) { return o.data.view_count == highest_votes && o.data.seconds > 60 });
console.log(obj);
JSON:
[
{
video_id: 'FOUKIZj74zs',
data: { seconds: 215, view_count: '81256' }
},
{
video_id: 'mepeWor5JPk',
data: { seconds: 168, view_count: '7874794' }
},
{
video_id: 'pTM_UaDxaEc',
data: { seconds: 67, view_count: '9729683' }
},
{
video_id: 'pFhQcfUUVGE',
data: { seconds: 313, view_count: '2967563' }
},
{
video_id: 'vbUTbqwKtEE',
data: { seconds: 191, view_count: '2089600' }
},
{
video_id: 'RYVOGcFaOQQ',
data: { seconds: 524, view_count: '1127662' }
},
{
video_id: 'X0PDYGKYVi4',
data: { seconds: 168, view_count: '375417' }
},
{
video_id: 'ecF50t2FHSA',
data: { seconds: 169, view_count: '295171' }
},
{
video_id: 'sK_3YIkTmVE',
data: { seconds: 60, view_count: '75604' }
},
{
video_id: 'p5h823w0rek',
data: { seconds: 280, view_count: '854952' }
}
]
Upvotes: 0
Views: 59
Reputation: 175
Divide the task in two. First you have to filter all the videos that have more that 60 seconds. After that you can reduce the result to 1 video that has the most views. Basically, all of this is a oneliner.
const result = arr.filter(elem=> {
const {data: {seconds}} = elem
return seconds > 60
}).reduce((acc, elem) => {
return (acc.data.view_count> elem.data.view_count? acc : elem)
})
Upvotes: 0
Reputation: 370979
Filter out the elements with below 60 seconds first, before identifying the highest number of views.
const videoDetails=[{video_id:"FOUKIZj74zs",data:{seconds:215,view_count:"81256"}},{video_id:"mepeWor5JPk",data:{seconds:168,view_count:"7874794"}},{video_id:"pTM_UaDxaEc",data:{seconds:67,view_count:"9729683"}},{video_id:"pFhQcfUUVGE",data:{seconds:313,view_count:"2967563"}},{video_id:"vbUTbqwKtEE",data:{seconds:191,view_count:"2089600"}},{video_id:"RYVOGcFaOQQ",data:{seconds:524,view_count:"1127662"}},{video_id:"X0PDYGKYVi4",data:{seconds:168,view_count:"375417"}},{video_id:"ecF50t2FHSA",data:{seconds:169,view_count:"295171"}},{video_id:"sK_3YIkTmVE",data:{seconds:60,view_count:"75604"}},{video_id:"p5h823w0rek",data:{seconds:280,view_count:"854952"}}];
const highestViews = Math.max(
...videoDetails
.filter(({ data}) => data.seconds >= 60)
.map(({ data }) => data.view_count)
);
console.log(videoDetails.find(({ data }) => Number(data.view_count) === highestViews));
Another approach would be to .reduce
, iterating over the array only once and storing the best element found so far as the accumulator.
const videoDetails=[{video_id:"FOUKIZj74zs",data:{seconds:215,view_count:"81256"}},{video_id:"mepeWor5JPk",data:{seconds:168,view_count:"7874794"}},{video_id:"pTM_UaDxaEc",data:{seconds:67,view_count:"9729683"}},{video_id:"pFhQcfUUVGE",data:{seconds:313,view_count:"2967563"}},{video_id:"vbUTbqwKtEE",data:{seconds:191,view_count:"2089600"}},{video_id:"RYVOGcFaOQQ",data:{seconds:524,view_count:"1127662"}},{video_id:"X0PDYGKYVi4",data:{seconds:168,view_count:"375417"}},{video_id:"ecF50t2FHSA",data:{seconds:169,view_count:"295171"}},{video_id:"sK_3YIkTmVE",data:{seconds:60,view_count:"75604"}},{video_id:"p5h823w0rek",data:{seconds:280,view_count:"854952"}}];
const output = videoDetails.reduce((bestSoFar, video) => {
if (video.data.seconds < 60) return bestSoFar;
return !bestSoFar || video.data.view_count > bestSoFar.data.view_count
? video
: bestSoFar;
});
console.log(output);
Upvotes: 3