Add element based on array comparison

Asked

Viewed 52 times

0

I have two arrays:

videos = [{
  "id": number,
  "title": string,
  "url": string
}]

watched = [{
  "video_id": number
}]

"video_id" is added when a user watches a specific video, this ID is the same as in the videos array.

I need to compare the two arrays, add the "Watched" element based on the following comparison: id === video_id. For example:

videos = [{
    "id": 1,
    "title": "one",
    "url": "/v1",
    "watched": true
  }, {
    "id": 2,
    "title": "two",
    "url": "/v2"
    "watched": false
  }
];

For now I have compared the objects containing the matching Ids as follows:

const watched_video = watched
      .filter((x) => x.watched)
      .map((x) => x.video_id);

However, I don’t know how to add the watched: true the element that has matching id’s and watched: false to those who do not possess.

Edit:

Based on the answers, I was able to solve the problem with the following code:

const watched_video = videos.map((v) => {
  if (watched.some((w) => w.video_id === v.id))
    return { ...v.dataValues, watched: true };
  return { ...v.dataValues, watched: false };
});
  • I couldn’t understand it. This array watched has an object of property watched or not? By your code only "video_id".

  • You want to add the attribute watched in the array videos on the basis of ids that are in watched?

  • That’s right! I need to add the Watched attribute and make it true for all objects that video.id === Watched.video_id.

2 answers

2


Assuming you have an array with idof those who have already been assisted, the comparison can be made using only the map and returning the formatted object according to one condition (if the id of this object is in the list of assisted watched).

This is only one possible soulção that you can use. If I understand your question correctly, you can do the following...

See the code:

const videos = [
  {
    id: 1,
    title: 'one',
    url: '/v1',
  },
  {
    id: 2,
    title: 'two',
    url: '/v2',
  },
  {
    id: 3,
    title: 'two',
    url: '/v2',
  },
  {
    id: 4,
    title: 'two',
    url: '/v2',
  },
  {
    id: 5,
    title: 'two',
    url: '/v2',
  },
  {
    id: 6,
    title: 'two',
    url: '/v2',
  },
];

const watched = [1, 3, 4];

const watched_video = videos.map((el) => {
  if (watched.includes(el.id)) return { ...el, watched: true };
  else return { ...el, watched: false };
});

console.log(watched_video);

  • if(watched.includes(el.id)) (just example, ignore this way as I wrote) is just a nod to check whether the id is on the list of assisted.

  • We use includes to check whether the id of the object is in the list of assisted.

  • The if/else is used to format and set the value of watched.

  • Got it! I changed the question of checking a little, but it worked right! I’m only having a problem returning this as a JSON, I get the following error: Converting circular Structure to JSON n

  • I did not understand the error message. Used JSON.stringify?

  • See gist: https://gist.github.com/fredarend/fcdf011502eecb0f2675e19fce093b62 Includes some comments explaining.

  • 1

    Solved. I edited the question.

2

Making a change in array nomenclature watched_video for watches and assuming that the ids in the arrays videos and watches are unique it is possible to create an instance of Set through the method of Set.prototype.add(), store unique values of any kind. In this case the assisted video ids.
The instances Set also have the method Set.prototype.has() that returns a boolean value indicating whether or not the element is contained in that set.

Aware of this information just iterate through the array watches and save the identities of the movies watched on Set named for ids and then iterate through the array videos and for each element add the property watched.

let videos = [
  {"id": 1, "title": "one", "url": "/v1"},
  {"id": 2, "title": "two", "url": "/v2"},
  {"id": 3, "title": "three", "url": "/v3"},
  {"id": 4, "title": "four", "url": "/v4"},
]

let watches = [
  {"watched": true, "video_id": 1},
  {"watched": false, "video_id": 3},
  {"watched": true, "video_id": 4},
  {"watched": false,"video_id": 2}
]

let ids = new Set();                      //Inicializa o Set ids.

//Para cada elemento w de watches...
for (let w of watches) {
  if (w.watched) ids.add(w.video_id);     //...Se w.watched for true adiciona w.video_id em ids.
}

//Para cada elemento v de videos...
for (let v of videos) {
  v.watched = ids.has(v.id);             //...adiciona a propriedade watched ao elemento 
                                         //com o valor dependente de estar ou não contido em ids.
}

console.log(videos);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.