Mic*_*ael 18 javascript arrays jquery object
更新:
我有一个被称为对象的数组,cars其中包含带有关于汽车的属性数据的li标签(例如价格,汽车类型等).我的目标是根据某些标准将这些汽车整合到一个单一的列表中.
要求

汽车阵列:
<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 & 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 & 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>
Run Code Online (Sandbox Code Playgroud)
预期产出:
在上面的示例数组中,第一个和第三个列表应该匹配(因为它们具有相同的车型,位置ID,车辆示例等).第一个列表应该从数组中删除,因为它没有类别列表预付费,并且.column-price中的HTML应该添加到其预付费匹配中(在此示例中,数组中的第3个列表).
最终产品:
码:
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;
}, []);
Run Code Online (Sandbox Code Playgroud)
正如评论中所提到的,使用reduce会将复杂性保持在O(n).这基本上意味着,两倍大小的列表将花费两倍的时间,因为算法仅迭代汽车列表一次.
如果你需要将汽车数组中的每个项目与汽车数组中的每个其他项目进行比较,那么类似循环的方法的复杂性将达到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);
}
});
}, [];
Run Code Online (Sandbox Code Playgroud)
另一种方法是构建一个数据结构,允许在恒定时间内根据属性访问元素(O(1)).一个例子是(哈希)地图.在这种情况下,对于算法循环的每个元素,不需要再次遍历整个列表以识别匹配,而是查询Map结构的匹配.
额外:鉴于汽车是HTMLElement,您可以使用dataset属性更轻松地访问data-*值:
car.dataset.originalPrice === car.dataset.price
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请访问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 /降低
我完全不同地处理这个问题.为了帮助您入门,以下解决方案应该让您走上正确的道路.根据提供的数据集,它还应满足您的所有(或大多数)要求.
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]
}
}
})
Run Code Online (Sandbox Code Playgroud)
-
它是如何工作的?
carAttrsId.[O(1)查询]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" => {…}
Run Code Online (Sandbox Code Playgroud)
-
更新 - 改进了以前的代码并添加了按要求将项目转换为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")
})
Run Code Online (Sandbox Code Playgroud)
输出:
<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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
422 次 |
| 最近记录: |