Matching Objects in Array and Consolidate

I have an array of objects called cars that contains li tags with attribute data about cars (such as price, car type, etc.). My goal is to consolidate these cars into one single listing if they are a match based on certain criteria.

Requirements

  1. Fast Performance
  2. Only reduce or remove cars/listings from array that are a match. Other elements in the array should not be removed.
  3. If there is a match (based on criteria in if statement), then remove these matched elements (either car or car2) from the array if it does not have class “listing-prepaid”.
  4. For the matched element that was removed, get its data-price value and add button to the matching li listing-prepaid counterpart

Cars Array:

<li data-location-id="SX-34.0910834--118.352194" data-dropoff-location-id="SX-34.0910834--118.352194" data-type="ICAR" data-price="180.15" data-original-price="" data-vehicle-example="Chevrolet Cruze" class="listing"></li>
<li data-location-id="ZR-34.1958--118.3489" data-dropoff-location-id="ZR-34.1958--118.3489" data-type="IDAR" data-price="301.43" data-vehicle-example="Toyota Corolla" class="listing"></li>
<li data-location-id="SX-34.0910834--118.352194" data-dropoff-location-id="SX-34.0910834--118.352194" data-type="ICAR" data-price="147.91" data-original-price="180.15" data-vehicle-example="Chevrolet Cruze" class="listing-prepaid"></li>
<li data-location-id="FX-34.0629025--117.6140867" data-dropoff-location-id="FX-34.0629025--117.6140867" data-partner-code="FX" data-type="SCAR" data-price="198.81" class="listing"></li>

Expected Output:

In the above example array, the first and third listings should match. The first listing should be removed from the array since it does not have class listing-prepaid.

Code:

 // Should I be using reduce if I only want to reduce/remove
 // cars/listings that have attributes that match?
 cars = cars.reduce(function (acc, car) {
	
       // Is there a way to get this to work without using forEach?
       // I'm seeing a performance hit with using forEach
       cars.forEach(function(car2) {
		
            // Match Logic - based on comparing attributes
            if (((car.data("originalPrice") !== undefined && car.data("originalPrice") === car2.data("price")) || (car2.data("originalPrice") !== undefined && car2.data("originalPrice") === car.data("price"))) && (car.data("basePrice") != car2.data("basePrice")) && (car.data("price") != car2.data("price")) && (car.data("type") == car2.data("type")) && (car.data("vehicleExample") == car2.data("vehicleExample")) && (car.data("locationId") == car2.data("locationId")) && (car.data("dropoffLocationId") == car2.data("dropoffLocationId")))
		    {
			    acc.push(car2);
		    }
	    });
	    return acc;
 }, []);

Might sound odd, but the advice you receive may vary depending upon it…

How do you originally define cars?

You might filter the cars by iterating over the dataset keys of the compare item and checking each for equality like so:

var getDataMatches = function (list, compareItem) {
  var keys = Object.keys(compareItem.dataset)

  return list.filter(function (item) {
    return keys.every(function (key) {
      return item.dataset[key] === compareItem.dataset[key]
    })
  })
}

This will only take into account dataset properties that are actually present on the compare item, but you can of course specify a predefined list as well.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.