Сопоставление объектов в массиве и консолидации - PullRequest
0 голосов
/ 10 мая 2018

ОБНОВЛЕНИЕ:

У меня есть массив объектов с именем cars, который содержит теги li с данными атрибутов об автомобилях (таких как цена, тип автомобиля и т. Д.).Моя цель - объединить эти автомобили в один листинг, если они соответствуют определенным критериям.

Требования

  1. Быстрая производительность
  2. Сохранение структуры массива одинаковых автомобилей
  3. Основная цель: Сопоставление списков с предоплатой и розничной продажей - объедините HTML-код из списка розничной торговли (например, информацию о кнопках и ценах) в список с предоплатой.См .: enter image description here
  4. Если есть совпадение (на основе критериев в выражении IF), удалите сопоставленный список без класса «list-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>

Ожидаемый объем производства:

В приведенном выше массиве примеров первый и третий списки должны совпадать (поскольку они имеют одинаковый тип автомобиля, идентификаторы местоположения, пример транспортного средства и т. Д.).Первый листинг должен быть удален из массива, так как у него нет предоплаты по списку классов, а HTML-код внутри .column-price должен быть добавлен в совпадение с предоплатой (в данном примере это третий листинг в массиве).

Конечный продукт:

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 голосов
/ 15 мая 2018

В коде была ошибка, например, когда вы получаете доступ к элементу HTML из массива в js, он возвращает строки вместо объекта 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/
0 голосов
/ 11 мая 2018

Я бы подошел к этой проблеме совсем по-другому.Чтобы начать, следующее решение должно указать вам правильный путь.Исходя из предоставленного набора данных, он также должен соответствовать всем (или большинству) ваших требований.

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>
0 голосов
/ 14 мая 2018

Не уверен, что я понимаю вопрос, но этот код аналогичен вашему подходу, за исключением того, что 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;
} );
0 голосов
/ 10 мая 2018

Как уже упоминалось в комментариях, использование Reduce сохраняет сложность на O (n) . По сути, это означает, что список, вдвое превышающий размер, займет вдвое больше времени, поскольку алгоритм только один раз повторяет список автомобилей.

Если вам нужно сравнить каждый элемент в массиве cars с другим элементом в массиве cars, сложность с циклическими подходами будет ne 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 для доступа к данным - * значения проще с:

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/HTMLElement, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...