0

I have an array of objects, from which I want to filter distinct movie titles and create another array of objects.

    var movs = [
        {
            "Id": 3446,
            "FilmId": "ST00000358",
            "FilmPackageId": null,
            "Title": "Harry Potter and the Goblet of Fire",
        },
        {
            "Id": 3447,
            "FilmId": "ST00000358",
            "FilmPackageId": null,
            "Title": "Harry Potter and the Goblet of Fire",
        },
        {
            "Id": 3448,
            "FilmId": "ST00000359",
            "FilmPackageId": null,
            "Title": "Harry Potter and the Order of the Phoenix",
        },
        {
            "Id": 3449,
            "FilmId": "ST00000360",
            "FilmPackageId": null,
            "Title": "Spider-Man: Into The Spider-Verse",
        },
        {
            "Id": 3450,
            "FilmId": "ST00000360",
            "FilmPackageId": null,
            "Title": "Spider-Man: Into The Spider-Verse",
        }
    ]

I want to create an array of objects, which filter down to the distinct movie title and its id.


    [
        {
            Title: 'Harry Potter and the Goblet of Fire',
            FilmId: 'ST00000358'
        },
        {
            Title: 'Harry Potter and the Order of the Phoenix',
            FilmId: 'ST00000359'
        },
        {
            Title: 'Spider-Man: Into The Spider-Verse',
            FilmId: 'ST00000360'
        }
    ]

I have successfully got an array of distinct titles, with the below, but if i add additional fields to the map, it returns the whole array, not the distinct few.


    const movies = [...new Set(movs.map(item => item.Title))];

this does not work:

const movies = [
    ...new Set(
      movs.map((obj) => ({ label: obj.Title, value: obj.FilmId }))
    )
  ];
4
  • 1
    JavaScript doesn't compare objects based on the contents. {a: 1} !== {a: 1} Commented Aug 13, 2020 at 23:09
  • 1
    Reduce could help. Commented Aug 13, 2020 at 23:11
  • You could map + Set an array of FilmId, and from that resulting list map an array of a single element found using each FilmId Commented Aug 13, 2020 at 23:12
  • Does this answer your question? Create array of unique objects by property Commented Aug 13, 2020 at 23:14

3 Answers 3

2

This is caused by how JS compares Objects and Strings (strings by value, object by reference), so

{k:1} === {k:1} === false

in order to get this kind of set you can use something like reduce:

var movs = [
   {
       "Id": 3446,
       "FilmId": "ST00000358",
       "FilmPackageId": null,
       "Title": "Harry Potter and the Goblet of Fire",
   },
   {
       "Id": 3447,
       "FilmId": "ST00000358",
       "FilmPackageId": null,
       "Title": "Harry Potter and the Goblet of Fire",
   },
   {
       "Id": 3448,
       "FilmId": "ST00000359",
       "FilmPackageId": null,
       "Title": "Harry Potter and the Order of the Phoenix",
   },
   {
       "Id": 3449,
       "FilmId": "ST00000360",
       "FilmPackageId": null,
       "Title": "Spider-Man: Into The Spider-Verse",
   },
   {
       "Id": 3450,
       "FilmId": "ST00000360",
       "FilmPackageId": null,
       "Title": "Spider-Man: Into The Spider-Verse",
   }
]

console.log(Object.values(movs.reduce((acc, {FilmId, Title}) => (acc[FilmId] = {Title, FilmId}, acc), {})));

Sign up to request clarification or add additional context in comments.

Comments

1

You can filter based on a specific key using a Set and then use map.

var movs = [{ "Id": 3446, "FilmId": "ST00000358", "FilmPackageId": null, "Title": "Harry Potter and the Goblet of Fire", }, { "Id": 3447, "FilmId": "ST00000358", "FilmPackageId": null, "Title": "Harry Potter and the Goblet of Fire", }, { "Id": 3448, "FilmId": "ST00000359", "FilmPackageId": null, "Title": "Harry Potter and the Order of the Phoenix", }, { "Id": 3449, "FilmId": "ST00000360", "FilmPackageId": null, "Title": "Spider-Man: Into The Spider-Verse", }, { "Id": 3450, "FilmId": "ST00000360", "FilmPackageId": null, "Title": "Spider-Man: Into The Spider-Verse", } ];
let set = new Set();
const res = movs.filter(({FilmId})=>!set.has(FilmId) && set.add(FilmId)).map(({Title,FilmId})=>({Title,FilmId}));
console.log(res);

Comments

0

You could even use forEach to do the job:

var movs = [{ "Id": 3446, "FilmId": "ST00000358", "FilmPackageId": null, "Title": "Harry Potter and the Goblet of Fire", }, { "Id": 3447, "FilmId": "ST00000358", "FilmPackageId": null, "Title": "Harry Potter and the Goblet of Fire", }, { "Id": 3448, "FilmId": "ST00000359", "FilmPackageId": null, "Title": "Harry Potter and the Order of the Phoenix", }, { "Id": 3449, "FilmId": "ST00000360", "FilmPackageId": null, "Title": "Spider-Man: Into The Spider-Verse", }, { "Id": 3450, "FilmId": "ST00000360", "FilmPackageId": null, "Title": "Spider-Man: Into The Spider-Verse", } ];

let sortedArray = [];
movs.forEach(({Title, FilmId}) => {return sortedArray[FilmId] = {Title, FilmId}});

console.log(Object.values(sortedArray));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.