匹配数组中的对象并进行合并

时间:2018-05-10 17:18:55

标签: javascript jquery arrays object

更新

我有一个名为cars的对象数组,其中包含带有关于汽车属性数据的li标签(例如价格,汽车类型等)。我的目标是根据某些标准将这些汽车整合到一个单一的列表中。

要求

  1. 快速表现
  2. 保持相同的汽车阵列结构
  3. 主要目标:匹配预付费和零售商列表 - 将零售商品列表中的HTML(例如按钮和定价信息)合并到预付费列表中。请参阅:enter image description here
  4. 如果匹配(基于IF声明中的标准),则删除匹配的列表,不要使用“listing-prepaid”类别,并使用零售列表中的某些信息更新匹配的预付列表。
  5. 汽车阵列:

    <li xmlns="http://www.w3.org/1999/xhtml" id="listing-CCAR-RM-AD-SFBT003-AD-SFBT003" data-location-id="AD-28.7455--81.2411" data-dropoff-location-id="AD-28.7455--81.2411" data-partner-name="Advantage" data-partner-code="AD" data-type="CCAR" data-vehicle-class-description="Compact Car" data-seats="5" data-bags="2" data-counter-type="ON_AIRPORT" data-prepaid="Y" data-fare-type="PREPAID" data-transmission="Automatic" data-unlimited-miles="Y" data-preferred="N" data-price="34.81" data-original-price="35.70" data-base-price="24.25" data-vehicle-example="Nissan Versa" data-highlighted="N" data-deal="Y" class="listing listing-prepaid" data-original-position="18"><div class="row"><div class="column column-images"><div class="img-wrapper"><ul class="icons"><li class="people"><span>5</span></li><li class="bags"><span>2</span></li></ul></div></div><div class="column car-details"><div class="car-title"><h3><a><span class="car-class">Compact</span><b></b></a></h3><span class="car-example">Nissan Versa or similar<sup>†</sup></span><span class="counter-type airport">Car on Airport</span></div><div class="features"><span>Unlimited Miles</span></div><div class="car-location-container"><div class="car-location"><h6>Pick-up</h6>SFB: Orlando Sanford Intl Airport</div><div class="car-location"><h6>Drop-off</h6>Same as pick-up</div></div></div><div class="column column-price"><span class="car-badge prepaid">Pay Now &amp; Save 2%</span><div class="container retail prepaid"><div class="rate"><span class="strikethrough"><span class="price-original">$25</span></span><span class="cur-symbol">$</span><span class="price">24</span><span class="rate-plan">/day</span></div><p class="button"><a class="button">Pay Now</a></p><span class="total">Total: $<span class="price">34</span></span></div></div></div><b style="clear:both;display:block;height:1px;width:1px"></b></li>
    
    <li xmlns="http://www.w3.org/1999/xhtml" id="listing-ECAR-RP-HZ-ORLN003-HZ-ORLN003" data-location-id="HZ-28.5042--81.4284" data-dropoff-location-id="HZ-28.5042--81.4284" data-partner-name="Hertz" data-partner-code="HZ" data-type="ECAR" data-vehicle-class-description="Economy Car" data-seats="4" data-bags="1" data-counter-type="" data-prepaid="Y" data-fare-type="PREPAID" data-transmission="Automatic" data-unlimited-miles="Y" data-preferred="N" data-price="36.34" data-original-price="39.95" data-base-price="29.83" data-vehicle-example="Chevrolet Spark" data-highlighted="N" data-deal="Y" class="listing listing-prepaid" data-original-position="30"><div class="row"><div class="column column-images"><div class="img-wrapper"><ul class="icons"><li class="people"><span>4</span></li><li class="bags"><span>1</span></li></ul></div></div><div class="column car-details"><div class="car-title"><h3><a><span class="car-class">Economy</span><b></b></a></h3><span class="car-example">Chevrolet Spark or similar<sup>†</sup></span></div><div class="features"><span>Unlimited Miles</span></div><div class="car-location-container"><div class="car-location"><h6>Pick-up</h6>3575 Vineland Road, Orlando, FL</div><div class="car-location"><h6>Drop-off</h6>Same as pick-up</div></div></div><div class="column column-price"><span class="car-badge prepaid">Pay Now &amp; Save 9%</span><div class="container retail prepaid"><div class="rate"><span class="strikethrough"><span class="price-original">$33</span></span><span class="cur-symbol">$</span><span class="price">29</span><span class="rate-plan">/day</span></div><p class="button"><a class="button">Pay Now</a></p><span class="total">Total: $<span class="price">36</span></span></div></div></div><b style="clear:both;display:block;height:1px;width:1px"></b></li>
    
    <li xmlns="http://www.w3.org/1999/xhtml" id="listing-CCAR-R-AD-SFBT003-AD-SFBT003" data-location-id="AD-28.7455--81.2411" data-dropoff-location-id="AD-28.7455--81.2411" data-partner-name="Advantage" data-partner-code="AD" data-type="CCAR" data-vehicle-class-description="Compact Car" data-seats="5" data-bags="2" data-counter-type="ON_AIRPORT" data-prepaid="N" data-fare-type="RETAIL" data-transmission="Automatic" data-unlimited-miles="Y" data-preferred="N" data-price="35.70" data-base-price="25.00" data-vehicle-example="Nissan Versa" data-highlighted="N" data-deal="N" class="listing" data-original-position="22"><div class="row"><div class="column column-images"><div class="img-wrapper"><ul class="icons"><li class="people"><span>5</span></li><li class="bags"><span>2</span></li></ul></div></div><div class="column car-details"><div class="car-title"><h3><a><span class="car-class">Compact</span><b></b></a></h3><span class="car-example">Nissan Versa or similar<sup>†</sup></span><span class="counter-type airport">Car on Airport</span></div><div class="features"><span>Free Cancellation</span><span>Pay at Pick-up</span><span>Unlimited Miles</span></div><div class="car-location-container"><div class="car-location"><h6>Pick-up</h6>SFB: Orlando Sanford Intl Airport</div><div class="car-location"><h6>Drop-off</h6>Same as pick-up</div></div></div><div class="column column-price"><div class="container retail"><div class="rate"><span class="cur-symbol">$</span><span class="price">25</span><span class="rate-plan">/day</span></div><p class="button"><a class="button">Select Car</a></p><span class="total">Total: $<span class="price">35</span></span></div></div></div><b style="clear:both;display:block;height:1px;width:1px"></b></li>
    
    <li xmlns="http://www.w3.org/1999/xhtml" id="listing-ECAR-R-EX-MCOO001-EX-MCOO001" data-location-id="EX-28.4514095--81.3577729" data-dropoff-location-id="EX-28.4514095--81.3577729" data-partner-name="Executive" data-partner-code="EX" data-type="ECAR" data-vehicle-class-description="Economy Car" data-seats="2" data-bags="1" data-counter-type="OFF_AIR_SHTL" data-prepaid="N" data-fare-type="RETAIL" data-transmission="Automatic" data-unlimited-miles="Y" data-preferred="N" data-price="28.78" data-base-price="14.58" data-vehicle-example="SmartCar" data-highlighted="N" data-deal="N" class="listing" data-original-position="2"><div class="row"><div class="column column-images"><div class="img-wrapper"><ul class="icons"><li class="people"><span>2</span></li><li class="bags"><span>1</span></li></ul></div></div><div class="column car-details"><div class="car-title"><h3><a><span class="car-class">Economy</span><b></b></a></h3><span class="car-example">SmartCar or similar<sup>†</sup></span><span class="counter-type shuttle">Shuttle to Car</span></div><div class="features"><span>Pay at Pick-up</span><span>Unlimited Miles</span></div><div class="car-location-container"><div class="car-location"><h6>Pick-up</h6>MCO: Orlando Intl Airport</div><div class="car-location"><h6>Drop-off</h6>Same as pick-up</div></div></div><div class="column column-price"><div class="container retail"><div class="rate"><span class="cur-symbol">$</span><span class="price">14</span><span class="rate-plan">/day</span></div><p class="button"><a class="button">Select Car</a></p><span class="total">Total: $<span class="price">28</span></span></div></div></div><b style="clear:both;display:block;height:1px;width:1px"></b></li>
    

    预期输出:

    在上面的示例数组中,第一个和第三个列表应该匹配(因为它们具有相同的车型,位置ID,车辆示例等)。第一个列表应该从数组中删除,因为它没有类别列表预付费,并​​且.column-price中的HTML应该添加到其预付费匹配中(在此示例中,数组中的第3个列表)。 < / p>

    最终产品:

    enter image description here

    代码:

     cars = cars.reduce((acc, car) => {
        let retail_match = false;
        cars.forEach(car2 => {
    
            if (((car[0].hasAttribute("data-original-price") && car[0].getAttribute("data-original-price") === car2[0].getAttribute("data-price")) || (car2[0].hasAttribute("data-original-price") && car2[0].getAttribute("data-original-price") === car[0].getAttribute("data-price"))) && (car[0].getAttribute("data-base-price") != car2[0].getAttribute("data-base-price")) && (car[0].getAttribute("data-price") != car2[0].getAttribute("data-price")) && (car[0].getAttribute("data-type") == car2[0].getAttribute("data-type")) && (car[0].getAttribute("data-vehicle-example") == car2[0].getAttribute("data-vehicle-example")) && (car[0].getAttribute("data-location-id") == car2[0].getAttribute("data-location-id")) && (car[0].getAttribute("data-dropoff-location-id") == car2[0].getAttribute("data-dropoff-location-id")))
            {
                if (!car.hasClass("listing-prepaid"))
                    retail_match = true;
                else
                {
                    car.find(".column-price")
                        .addClass("prepaid-match")
                        .append(car2.find(".column-price div.retail"))
                        .find("div.retail:not(.prepaid) p.button a").text("Pay Later");
                }
            }
        });
        if (!retail_match)
            acc.push(car);
        return acc;
    }, []);
    

4 个答案:

答案 0 :(得分:8)

正如评论中所提到的,使用reduce可以保持 O(n)的复杂性。这基本上意味着,两倍大小的列表将花费两倍的时间,因为算法只迭代汽车列表一次。

如果您需要将cars数组中的每个项目与cars数组中的每个其他项目进行比较,那么类似循环的方法的复杂性将为 O(n ^ 2), item(粗略地说)将使用指数级更多的循环/时间。

我对您的javascript对象的数据结构并非100%肯定,但以下方法应该有效:

const allCars = []; // An array of cars, each item is a HTMLElement
let matchedCars = allCars.reduce((acc, car, cars) => {

   cars.forEach(car2 => {
       // For every car iterate over the cars array again to compare car to every item in the cars array (leave out this loop if you don't need the extensive comparison)

       if (car.hasAttribute("data-original-price") 
           && car2.getAttribute("data-original-price") === car.getAttribute("data-price")
          /* Add additional matching criteria here, you may access cars to get info about other cars than the current car */) {

            // Add the desired class for a match
            car.classList.add('listing-prepaid');

            // Add the matched car to the accumulator, so it ends up in the matchedCars array
            acc.push(car);
      }

   });
}, [];

另一种方法是构建一个数据结构,允许在恒定时间内根据属性访问元素( O(1))。一个例子是(Hash)Map。在这种情况下,对于算法循环的每个元素,不需要再次循环遍历整个列表以识别匹配,而是查询Map结构的匹配。

加分:鉴于 car 是HTMLElement,您可以使用数据集属性访问数据 - * 值更容易:

car.dataset.originalPrice === car.dataset.price

https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes

了解详情

一般来源:https://developer.mozilla.org/en-US/docs/Web/API/HTMLElementhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

答案 1 :(得分:5)

我完全不同地处理这个问题。为了帮助您入门,以下解决方案应该让您走上正确的道路。根据提供的数据集,它还应满足所有(或大多数)您的要求。

const carsUniq = new Map()

cars.forEach($car => {
  const cKeys = $car.data()
  const carAttrsId = [    
    cKeys.dropoffLocationId,
    cKeys.locationId,
    cKeys.type,
    cKeys.vehicleExample
  ].join('')

  const sCar = carsUniq.get(carAttrsId)
  if (!sCar) {
    carsUniq.set( carAttrsId, cKeys )
  } else {
    for(const c in sCar) {
      if ( !sCar[c] && cKeys[c] ) sCar[c] = cKeys[c]
    }
  }
})

-

它是如何运作的?

  1. 创建跟踪汽车的地图。
  2. 通过将特定的汽车道具引用到carAttrsId来确定汽车是否重复。 [O(1)查找]
  3. 如果在地图中找到汽车,它必须是重复的,因此我们将数据集合并为一个标准化对象。
  4. 最终结果是carsUniq.values()是一个数组,就像唯一车辆的对象一样。
  5. -

    根据您的数据集carsUniq将包含3辆独特的汽车

    "SX-34.0910834--118.352194SX-34.0910834--118.352194ICARChevrolet Cruze" => {…}
    "ZR-34.1958--118.3489ZR-34.1958--118.3489IDARToyota Corolla" => {…}
    "FX-34.0629025--117.6140867FX-34.0629025--117.6140867SCAR" => {…}
    

    -

    更新 - 改进了以前的代码并增加了根据要求将项目转换为li元素的功能。

    const carsUniq = new Map()
    
    cars.forEach($car => {
      const cKeys = $car.data()
      const { dropoffLocationId, locationId, type, vehicleExample } = cKeys
      const carAttrsId = dropoffLocationId + locationId + type + vehicleExample;
    
      const sCar = carsUniq.get(carAttrsId)
      if (!sCar) {
        carsUniq.set( carAttrsId, cKeys )
      } else {
        for(const c in sCar) {
          if ( !sCar[c] && cKeys[c] ) sCar[c] = cKeys[c]
        }
      }
    })
    
    const dasherizedCarKeys = new Map()
    const dasherizedData = str => {
      const k = dasherizedCarKeys.get(str)
      if (!k) {
        dasherizedCarKeys.set(str, 
           'data-' + str.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase())
      }
      return k
    }
    
    carsUniq.forEach(car => {
      const tCar = {}
      const carKeys = Object.keys(car).map(dasherizedData)
      for (const c in car) {
        tCar[dasherizedCarKeys.get(c)] = car[c]
      }
      $('<li>').attr(tCar).appendTo("#output")
    })
    

    输出:

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

答案 2 :(得分:3)

我不确定我是否理解这个问题,但此代码与您的方法类似,只是cars只会,基于示例数据,只有一个项目,这是数据中的第三个li。 (各种if条件的格式为便于查看。)

cars = cars.reduce( ( ca, car2, ci, a ) => {
    let b = $.isArray( ca ) ? ca : [];
    a.forEach( car => {
        if (
            (
                ( car.attr( 'data-original-price' ) && car.attr( 'data-original-price' ) === car2.attr( 'data-price' ) ) ||
                ( car2.attr( 'data-original-price' ) && car2.attr( 'data-original-price' ) === car.attr( 'data-price' ) )
            ) &&
            ( car.attr( 'data-base-price' ) !== car2.attr( 'data-base-price' ) ) &&
            ( car.attr( 'data-price' ) !== car2.attr( 'data-price' ) ) &&
            ( car.attr( 'data-type' ) === car2.attr( 'data-type' ) ) &&
            ( car.attr( 'data-vehicle-example' ) === car2.attr( 'data-vehicle-example' ) ) &&
            ( car.attr( 'data-location-id' ) === car2.attr( 'data-location-id' ) ) &&
            ( car.attr( 'data-dropoff-location-id' ) === car2.attr( 'data-dropoff-location-id' ) )
        ) {
            if ( car.hasClass( 'listing-prepaid' ) ) {
                car.find( '.column-price' )
                    .addClass( 'prepaid-match' )
                    .append( car2.find( '.column-price div.retail' ) )
                    .find( 'div.retail:not(.prepaid) p.button a' )
                        .text( 'Pay Later' );

                b.push( car );
            }
        }
    } );
    return b;
} );

答案 3 :(得分:3)

代码中有一个错误,例如,当您从js中的数组访问HTML元素时,它返回字符串而不是HTML对象,因此您无法访问它意味着您无法应用JS / Jquery hasAttribute和其他它上面的函数,我已修复它,你可以在小提琴上找到工作示例,链接如下:

    var cars = ['<li xmlns="http://www.w3.org/1999/xhtml" id="listing-CCAR-RM-AD-SFBT003-AD-SFBT003" data-location-id="AD-28.7455--81.2411" data-dropoff-location-id="AD-28.7455--81.2411" data-partner-name="Advantage" data-partner-code="AD" data-type="CCAR" data-vehicle-class-description="Compact Car" data-seats="5" data-bags="2" data-counter-type="ON_AIRPORT" data-prepaid="Y" data-fare-type="PREPAID" data-transmission="Automatic" data-unlimited-miles="Y" data-preferred="N" data-price="34.81" data-original-price="35.70" data-base-price="24.25" data-vehicle-example="Nissan Versa" data-highlighted="N" data-deal="Y" class="listing listing-prepaid" data-original-position="18"><div class="row"><div class="column column-images"><div class="img-wrapper"><ul class="icons"><li class="people"><span>5</span></li><li class="bags"><span>2</span></li></ul></div></div><div class="column car-details"><div class="car-title"><h3><a><span class="car-class">Compact</span><b></b></a></h3><span class="car-example">Nissan Versa or similar<sup>†</sup></span><span class="counter-type airport">Car on Airport</span></div><div class="features"><span>Unlimited Miles</span></div><div class="car-location-container"><div class="car-location"><h6>Pick-up</h6>SFB: Orlando Sanford Intl Airport</div><div class="car-location"><h6>Drop-off</h6>Same as pick-up</div></div></div><div class="column column-price"><span class="car-badge prepaid">Pay Now &amp; Save 2%</span><div class="container retail prepaid"><div class="rate"><span class="strikethrough"><span class="price-original">$25</span></span><span class="cur-symbol">$</span><span class="price">24</span><span class="rate-plan">/day</span></div><p class="button"><a class="button">Pay Now</a></p><span class="total">Total: $<span class="price">34</span></span></div></div></div><b style="clear:both;display:block;height:1px;width:1px"></b></li>', '<li xmlns="http://www.w3.org/1999/xhtml" id="listing-ECAR-RP-HZ-ORLN003-HZ-ORLN003" data-location-id="HZ-28.5042--81.4284" data-dropoff-location-id="HZ-28.5042--81.4284" data-partner-name="Hertz" data-partner-code="HZ" data-type="ECAR" data-vehicle-class-description="Economy Car" data-seats="4" data-bags="1" data-counter-type="" data-prepaid="Y" data-fare-type="PREPAID" data-transmission="Automatic" data-unlimited-miles="Y" data-preferred="N" data-price="36.34" data-original-price="39.95" data-base-price="29.83" data-vehicle-example="Chevrolet Spark" data-highlighted="N" data-deal="Y" class="listing listing-prepaid" data-original-position="30"><div class="row"><div class="column column-images"><div class="img-wrapper"><ul class="icons"><li class="people"><span>4</span></li><li class="bags"><span>1</span></li></ul></div></div><div class="column car-details"><div class="car-title"><h3><a><span class="car-class">Economy</span><b></b></a></h3><span class="car-example">Chevrolet Spark or similar<sup>†</sup></span></div><div class="features"><span>Unlimited Miles</span></div><div class="car-location-container"><div class="car-location"><h6>Pick-up</h6>3575 Vineland Road, Orlando, FL</div><div class="car-location"><h6>Drop-off</h6>Same as pick-up</div></div></div><div class="column column-price"><span class="car-badge prepaid">Pay Now &amp; Save 9%</span><div class="container retail prepaid"><div class="rate"><span class="strikethrough"><span class="price-original">$33</span></span><span class="cur-symbol">$</span><span class="price">29</span><span class="rate-plan">/day</span></div><p class="button"><a class="button">Pay Now</a></p><span class="total">Total: $<span class="price">36</span></span></div></div></div><b style="clear:both;display:block;height:1px;width:1px"></b></li>', '<li xmlns="http://www.w3.org/1999/xhtml" id="listing-CCAR-R-AD-SFBT003-AD-SFBT003" data-location-id="AD-28.7455--81.2411" data-dropoff-location-id="AD-28.7455--81.2411" data-partner-name="Advantage" data-partner-code="AD" data-type="CCAR" data-vehicle-class-description="Compact Car" data-seats="5" data-bags="2" data-counter-type="ON_AIRPORT" data-prepaid="N" data-fare-type="RETAIL" data-transmission="Automatic" data-unlimited-miles="Y" data-preferred="N" data-price="35.70" data-base-price="25.00" data-vehicle-example="Nissan Versa" data-highlighted="N" data-deal="N" class="listing" data-original-position="22"><div class="row"><div class="column column-images"><div class="img-wrapper"><ul class="icons"><li class="people"><span>5</span></li><li class="bags"><span>2</span></li></ul></div></div><div class="column car-details"><div class="car-title"><h3><a><span class="car-class">Compact</span><b></b></a></h3><span class="car-example">Nissan Versa or similar<sup>†</sup></span><span class="counter-type airport">Car on Airport</span></div><div class="features"><span>Free Cancellation</span><span>Pay at Pick-up</span><span>Unlimited Miles</span></div><div class="car-location-container"><div class="car-location"><h6>Pick-up</h6>SFB: Orlando Sanford Intl Airport</div><div class="car-location"><h6>Drop-off</h6>Same as pick-up</div></div></div><div class="column column-price"><div class="container retail"><div class="rate"><span class="cur-symbol">$</span><span class="price">25</span><span class="rate-plan">/day</span></div><p class="button"><a class="button">Select Car</a></p><span class="total">Total: $<span class="price">35</span></span></div></div></div><b style="clear:both;display:block;height:1px;width:1px"></b></li>', '<li xmlns="http://www.w3.org/1999/xhtml" id="listing-ECAR-R-EX-MCOO001-EX-MCOO001" data-location-id="EX-28.4514095--81.3577729" data-dropoff-location-id="EX-28.4514095--81.3577729" data-partner-name="Executive" data-partner-code="EX" data-type="ECAR" data-vehicle-class-description="Economy Car" data-seats="2" data-bags="1" data-counter-type="OFF_AIR_SHTL" data-prepaid="N" data-fare-type="RETAIL" data-transmission="Automatic" data-unlimited-miles="Y" data-preferred="N" data-price="28.78" data-base-price="14.58" data-vehicle-example="SmartCar" data-highlighted="N" data-deal="N" class="listing" data-original-position="2"><div class="row"><div class="column column-images"><div class="img-wrapper"><ul class="icons"><li class="people"><span>2</span></li><li class="bags"><span>1</span></li></ul></div></div><div class="column car-details"><div class="car-title"><h3><a><span class="car-class">Economy</span><b></b></a></h3><span class="car-example">SmartCar or similar<sup>†</sup></span><span class="counter-type shuttle">Shuttle to Car</span></div><div class="features"><span>Pay at Pick-up</span><span>Unlimited Miles</span></div><div class="car-location-container"><div class="car-location"><h6>Pick-up</h6>MCO: Orlando Intl Airport</div><div class="car-location"><h6>Drop-off</h6>Same as pick-up</div></div></div><div class="column column-price"><div class="container retail"><div class="rate"><span class="cur-symbol">$</span><span class="price">14</span><span class="rate-plan">/day</span></div><p class="button"><a class="button">Select Car</a></p><span class="total">Total: $<span class="price">28</span></span></div></div></div><b style="clear:both;display:block;height:1px;width:1px"></b></li>'];
cars = cars.reduce((acc, car) => {
  let retail_match = false;
  cars.forEach(car2 => {

    if ((($(car)[0].hasAttribute("data-original-price") && $(car)[0].getAttribute("data-original-price") === $(car2)[0].getAttribute("data-price")) || ($(car2)[0].hasAttribute("data-original-price") && $(car2)[0].getAttribute("data-original-price") === $(car)[0].getAttribute("data-price"))) && ($(car)[0].getAttribute("data-base-price") != $(car2)[0].getAttribute("data-base-price")) && ($(car)[0].getAttribute("data-price") != $(car2)[0].getAttribute("data-price")) && ($(car)[0].getAttribute("data-type") == $(car2)[0].getAttribute("data-type")) && ($(car)[0].getAttribute("data-vehicle-example") == $(car2)[0].getAttribute("data-vehicle-example")) && ($(car)[0].getAttribute("data-location-id") == $(car2)[0].getAttribute("data-location-id")) && ($(car)[0].getAttribute("data-dropoff-location-id") == $(car2)[0].getAttribute("data-dropoff-location-id"))) {
      if (!$(car).hasClass("listing-prepaid"))
        retail_match = true;
      else {
        $(car).find(".column-price")
          .addClass("prepaid-match")
          .append($(car2).find(".column-price div.retail"))
          .find("div.retail:not(.prepaid) p.button a").text("Pay Later");
      }

      console.log(retail_match);
    }
  });
  if (!retail_match)
    acc.push(car);
  return acc;
}, []);

console.log(cars);

[jsfiddle][1]


I hope this will solve your issue, Let me know if you've any question. Thanks


  [1]: https://jsfiddle.net/harshsri/93qbghgk/