user10585730
user10585730

Reputation:

Comparing two arrays of objects

I have an array containing a list of cars, and an image URL.

On the page, i have a list of lots of cars. I want to loop over all cars on page, and if it is within the cars array, then I want to swap it's image to the new one.

What would be the best way to go about this?

<!-- example of on page list of cars -->

<li class="car" data-id="car1">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car12">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car2">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car7">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

--

const cars = [
    {
        "id": "car1"
        "newImage": "imageaddress1"
    },
    {
        "id": "car2"
        "newImage": "imageaddress2"
    },
    {
        "id": "car3"
        "newImage": "imageaddress3"
    },
]

const allCarsNodeList = document.querySelectorAll('.car');
const allCars = Array.from(allProductsNodeList);

First thoughts are to use filter to reduce the on page cars down to only the ones featured, but I'm lost on how to do the comparison since in neither the array or the on page data-attribute are directly there.

I'm confused basically! Any points in the right direction would be greatly appreciated.

Upvotes: 1

Views: 78

Answers (5)

Sim Dim
Sim Dim

Reputation: 582

Since your cars are stored in an array with a unique id, I would recommend converting this cars array into a dictionary first (this will increase performance):

const cars = [
    {
        "id": "car1",
        "newImage": "imageaddress1"
    },
    {
        "id": "car2",
        "newImage": "imageaddress2"
    },
    {
        "id": "car3",
        "newImage": "imageaddress3"
    }
]

// create cars dictionary from carsList
const carsDictionary = cars.reduce((r, car) => {
    r[car.id] = car;
    return r;
}, {});

// iterate over nodes with car class
const carNodesDict = Array.from(document.querySelectorAll('.car'))
.forEach((node) => {
    const car = carsDictionary[node.dataset.id];
    if (car != null) {
      node.querySelector('img').src = car.newImage;
    }
});
<!-- example of on page list of cars -->

<li class="car" data-id="car1">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car12">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car2">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car7">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

Upvotes: 0

Nikhil Aggarwal
Nikhil Aggarwal

Reputation: 28445

You can try following

  • First create an object from cars array with id as key and image url as value
  • Now, iterate over the array and see whether the element's id exist in the object created above. If it exists, update the src of corresponding img

const cars = [{"id": "car1","newImage": "imageaddress1"},{"id": "car2","newImage": "imageaddress2"},{"id": "car3","newImage": "imageaddress3"}];
// Create a map of id and newImage
const obj = cars.reduce((a,c) => Object.assign(a, {[c.id] : c.newImage}), {});
// Get all cars 
const allCars = Array.from(document.querySelectorAll('.car'));
// Iterate over cars
allCars.forEach(c => {
  //if entry exists in the object, update corresponding image
  if(obj[c.dataset.id]) c.querySelector("img").src = obj[c.dataset.id];
});
<li class="car" data-id="car1">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car12">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car2">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car7">
    <img src="https://imageurl.com/currentImage" alt="">
</li>

Upvotes: 1

gavgrif
gavgrif

Reputation: 15499

Iterate over the results in the node list and compare the data-id to the id of the cars array. If it matches - swap the src attribute to the newImage.

I am also updating the alt attribute so that you can see the src has changes (since I don't have your images)

const cars = [
    {
        "id": "car1",
        "newImage": "imageaddress1"
    },
    {
        "id": "car2",
        "newImage": "imageaddress2"
    },
    {
        "id": "car3",
        "newImage": "imageaddress3"
    },
]


const allCarsNodeList = document.querySelectorAll('.car');

allCarsNodeList.forEach(function(car, index){
  var id = car.getAttribute('data-id');
  var image = car.querySelector('img');
  cars.forEach(function(carItem){
     if(carItem.id == id) {
      image.setAttribute('src', carItem.newImage);
      image.setAttribute('alt', carItem.newImage) ;
     }
   })
})
<ul>
  <li class="car" data-id="car1">
      <img src="https://imageurl.com/currentImage" alt="currentImage">
  </li>

  <li class="car" data-id="car12">
      <img src="https://imageurl.com/currentImage" alt="currentImage">
  </li>

  <li class="car" data-id="car2">
      <img src="https://imageurl.com/currentImage" alt="currentImage">
  </li>

  <li class="car" data-id="car7">
      <img src="https://imageurl.com/currentImage" alt="currentImage">
  </li>

</ul>

Upvotes: 0

Dorian B
Dorian B

Reputation: 150

This work for me :

    const allCarsNodeList = document.querySelectorAll('.car');
    const allCars = Array.from(allCarsNodeList);
    console.log(allCars)
    allCars.forEach(car => {
        carId = car.dataset.id
        correspondingCar = cars.filter(each => each.id === carId)[0]
        console.log(correspondingCar);
        if (correspondingCar !== undefined) {
            car.children[0].src = correspondingCar.newImage
        }
    })

Upvotes: 0

Ankit Agarwal
Ankit Agarwal

Reputation: 30739

You need to follow these steps:

  1. Get all the elements with class car
  2. Loop through that element and find the data-id value of each element
  3. Use that data-id value to find a matching object in cars array
  4. If a object is found then replace the src attribute of that image which is inside the .car element with the newImage value of the object.

const cars = [{
    "id": "car1",
    "newImage": "imageaddress1"
  },
  {
    "id": "car2",
    "newImage": "imageaddress2"
  },
  {
    "id": "car3",
    "newImage": "imageaddress3"
  }
]

const allCarsNodeList = document.querySelectorAll('.car');
for (var i = 0; i < allCarsNodeList.length; i++) {
  var carId = allCarsNodeList[i].dataset.id;
  var matchCar = cars.find(({id}) => carId === id);
  if (matchCar) {
    allCarsNodeList[i].querySelector('img').src = matchCar.newImage;
  }
}
<li class="car" data-id="car1">1
  <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car12">2
  <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car2">3
  <img src="https://imageurl.com/currentImage" alt="">
</li>

<li class="car" data-id="car7">4
  <img src="https://imageurl.com/currentImage" alt="">
</li>

Use inspect element on the output to check that the src attribute is actually changed by the value of the newImage

Upvotes: 0

Related Questions