[英]What would be the most efficient way to find an object in an array of objects with distinct value which is an array?
I initially got this question in an interview few months back & have gotten around to solve it now.我最初在几个月前的一次采访中得到了这个问题,现在已经开始解决它了。
So we have this array of objects & the goal is to find an an object with actors that haven't appeared in a movie more than once.所以我们有这个对象数组,目标是找到一个对象,其中的演员在电影中没有出现过不止一次。 So basically find a movie with unique actors.所以基本上找一部有独特演员的电影。
[
{
name: 'The Dark Knight',
rating: 'PG-13',
year: 2012,
bestScene: {
name: 'fight',
location: 'sewer',
sceneLength: 10,
actors: ['Christian Bale', 'Tom Hardy']
}
},
{
name: 'Good Burger',
rating: 'PG',
year: 1994,
bestScene: {
name: 'jump',
location: 'giant milkshake',
sceneLength: 5,
actors: ['Kenan Thompson', 'Kel Mitchell']
}
},
{
name: 'Sharknado 2: The Second One',
rating: 'TV-14',
year: 2013
},
{
name: 'The Big Short',
rating: 'R',
year: 2015,
bestScene: {
name: 'explanation',
location: 'casino',
sceneLength: 20,
actors: ['Christian Bale', 'Steve Carrell']
}
}
]
And a goal I have set for myself is to solve it using functional way so naturally we need to weed out objects with no bestScene
present like this:我为自己设定的一个目标是使用函数方式解决它,所以我们很自然地需要清除没有bestScene
对象,如下所示:
const moviesWithActorsPresent = movies.filter((movie) => movie.bestScene)
I could then use reduce
to construct an array of objects like this:然后我可以使用reduce
来构造一个这样的对象数组:
[
{ 'The Dark Knight': [ 'Christian Bale', 'Tom Hardy' ] },
{ 'Good Burger': [ 'Kenan Thompson', 'Kel Mitchell' ] },
{ 'The Big Short': [ 'Christian Bale', 'Steve Carrell' ] }
]
And then loop through using for
or forEach
& keep track of the actors in a temporary variable but that to me is not exactly an elegant solution.然后循环使用for
或forEach
并在临时变量中跟踪演员,但这对我来说并不是一个优雅的解决方案。
What CS concept we can use here to solve it efficiently?我们可以在这里使用什么 CS 概念来有效地解决它?
Once you have the moviesWithActorsPresent
, create an object (or Map) counting up the number of occurrences of each actor in the entire array.一旦你有了moviesWithActorsPresent
,就创建一个对象(或Map)来计算整个数组中每个actor出现的次数。 Then you can .find
an object for which .every
actor has a count of exactly 1:然后你可以.find
一个对象,它的.every
actor 的计数正好是 1:
const movies =[ { name: 'The Dark Knight', rating: 'PG-13', year: 2012, bestScene: { name: 'fight', location: 'sewer', sceneLength: 10, actors: ['Christian Bale', 'Tom Hardy'] } }, { name: 'Good Burger', rating: 'PG', year: 1994, bestScene: { name: 'jump', location: 'giant milkshake', sceneLength: 5, actors: ['Kenan Thompson', 'Kel Mitchell'] } }, { name: 'Sharknado 2: The Second One', rating: 'TV-14', year: 2013 }, { name: 'The Big Short', rating: 'R', year: 2015, bestScene: { name: 'explanation', location: 'casino', sceneLength: 20, actors: ['Christian Bale', 'Steve Carrell'] } } ]; const moviesWithActorsPresent = movies.filter((movie) => movie.bestScene) const actorCounts = moviesWithActorsPresent.reduce((a, { bestScene }) => { const { actors } = bestScene; return Object.assign( {}, // don't mutate a, // prior counts ...actors.map(actor => ({ [actor]: (a[actor] || 0) + 1 })) ); }, {}); const movieWithUniqueActors = moviesWithActorsPresent.find(({ bestScene }) => ( bestScene.actors.every(actor => actorCounts[actor] === 1) )); console.log(movieWithUniqueActors);
It almost certainly doesn't matter, but you can put the .filter
functionality into the .reduce
if you want:几乎可以肯定没有问题,但你可以把.filter
功能集成到.reduce
,如果你想:
const movies = [{ name: 'The Dark Knight', rating: 'PG-13', year: 2012, bestScene: { name: 'fight', location: 'sewer', sceneLength: 10, actors: ['Christian Bale', 'Tom Hardy'] } }, { name: 'Good Burger', rating: 'PG', year: 1994, bestScene: { name: 'jump', location: 'giant milkshake', sceneLength: 5, actors: ['Kenan Thompson', 'Kel Mitchell'] } }, { name: 'Sharknado 2: The Second One', rating: 'TV-14', year: 2013 }, { name: 'The Big Short', rating: 'R', year: 2015, bestScene: { name: 'explanation', location: 'casino', sceneLength: 20, actors: ['Christian Bale', 'Steve Carrell'] } } ]; const actorCounts = movies.reduce((a, { bestScene }) => { if (!bestScene) { return a; } const { actors } = bestScene; return Object.assign({}, // don't mutate a, // prior counts ...actors.map(actor => ({ [actor]: (a[actor] || 0) + 1 })) ); }, {}); const movieWithUniqueActors = movies.find(({ bestScene }) => ( bestScene.actors.every(actor => actorCounts[actor] === 1) )); console.log(movieWithUniqueActors);
You'd just need to create a function which groups films by actors
, and then take only those that have 1
film.您只需要创建一个films by actors
分组的函数,然后只选取具有1
部电影的那些。
const group = (data) => data .reduce((res, { name, bestScene }) => { ((bestScene || {}).actors || []).forEach(actor => { res[actor] = (res[actor] || []).concat(name); }); return res; }, {}); const solve = data => Object .entries(group(data)) .filter(([author, films]) => films.length === 1) const data = [ { name: 'The Dark Knight', rating: 'PG-13', year: 2012, bestScene: { name: 'fight', location: 'sewer', sceneLength: 10, actors: ['Christian Bale', 'Tom Hardy'] } }, { name: 'Good Burger', rating: 'PG', year: 1994, bestScene: { name: 'jump', location: 'giant milkshake', sceneLength: 5, actors: ['Kenan Thompson', 'Kel Mitchell'] } }, { name: 'Sharknado 2: The Second One', rating: 'TV-14', year: 2013 }, { name: 'The Big Short', rating: 'R', year: 2015, bestScene: { name: 'explanation', location: 'casino', sceneLength: 20, actors: ['Christian Bale', 'Steve Carrell'] } } ]; console.log(solve(data));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.