在数组中匹配对象并合并

18

更新:

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

要求:

  1. 快速性能
  2. 保持相同的汽车数组结构。
  3. 主要目标:匹配预付和零售列表-将零售列表中的HTML(例如按钮和定价信息)合并到预付列表中。请参见:enter image description here
  4. 如果存在匹配项(根据IF语句中的条件),则删除不带“listing-prepaid”类的匹配列表,并使用来自零售列表的某些信息更新匹配的预付列表。

汽车数组:

<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、车辆示例等)。第一个列表应该从数组中删除,因为它没有类“listing-prepaid”,并且“column-price”中的HTML内容应添加到其预付匹配项中(在本例中是数组中的第3个列表)。

最终产品:

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;
}, []);

car 不是一个数组,所以 car[0] 不应该起作用,只使用 car 即可... 如果我没有漏掉什么,对于 car2[0] 也应该是一样的。 - Asons
我认为使用reduce比filter更有意义。 - Patrick Hund
4个回答

8
如评论中所述,使用reduce可以将复杂度保持在O(n)。这基本上意味着,列表的大小增加一倍,时间也会增加一倍,因为该算法只迭代汽车列表一次。
如果需要将cars数组中的每个项与另一个项进行比较,则类似循环的方法的复杂度将是O(n^2),因为对于每个额外的项(粗略地说),将有指数级别更多的循环/时间使用。
我不100%确定您的javascript对象的数据结构,但以下方法应该有效:
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,您可以使用dataset属性更轻松地访问data-*值:
car.dataset.originalPrice === car.dataset.price

请阅读https://developer.mozilla.org/zh-CN/docs/Learn/HTML/Howto/Use_data_attributes,了解更多关于此的信息。

一般资源:https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElementhttps://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce


谢谢您的回复!如果我使用reduce,那么我不需要forEach吗?我该如何查看一辆车的data-price === 另一辆车的data-original-price? - Michael
不需要使用forEach。reduce方法遍历汽车列表,并将所有匹配的汽车推入acc数组中,该数组将从reduce方法返回。请参阅已调整的答案代码,了解如何获取汽车数组中的其他汽车。 - Capricorn
啊,好的。我看到你在 reduce 函数中添加了另一个参数 cars?因此,如果我想要检查 car.data("price") 是否等于其他车辆的 originalPrice... 我应该检查 car.data("price") == cars.data("originalPrice") 吗? - Michael
很遗憾,这在你的问题中没有明确说明。这需要在reduce函数中对整个cars数组进行额外的循环。你可以使用forEach来实现。 - Capricorn
嗨,迈克尔。根据您的要求,您需要对您的汽车数组进行两个嵌套迭代。如果您想要检查列表中的每辆汽车是否有与之匹配的其他汽车,则这是必要的。如果您在此过程中遇到性能问题,您可能需要在服务器上执行计算,而不是在浏览器上执行。在这种情况下,无论您使用reduce还是filter,在性能方面都没有影响。 - Capricorn
显示剩余4条评论

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()”是一个类似于唯一汽车对象的数组。
--
根据您的数据集“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>

嗨Fabb!谢谢你的帖子 :) 我正在运行代码...我非常喜欢这种方法,我该如何编辑它以返回实际的<li> html而不是数组中的对象信息? - Michael
你可以使用模板库在前端(如Angular、React、Vue等)创建li元素。这超出了本问题的范围。 - MrPizzaFace
嗯,我喜欢它的速度。然而,我的主要目标是将每个匹配元素的信息合并到一个列表中,同时修改现有的汽车数组。你能修改你的答案吗?如果没有表述清楚,对不起。 - Michael
请查看我的更新代码,以从唯一汽车数组创建li项。 - MrPizzaFace
1
你最新的更新显示了完全不同的汽车数组。你到底遇到了什么问题?我无法在无法复制你的确切环境的情况下提供精确的工作代码。我提供的代码仍然可以采用来解决你的问题。如果你想要精确的工作代码以满足你的规格,你应该创建一个codepen或jsbin进行复制。同时,向有帮助的任何解决方案点赞并接受是礼貌的。最后,StackOverflow的目的是帮助指导你,而不是为你工作。如果你无法通过帮助找到答案,你可能需要雇用某人来帮忙。 - MrPizzaFace
显示剩余9条评论

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

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

    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/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接