admin管理员组

文章数量:1315831

I need to write a function that takes in 2 arguments, the first argument is a list of <li> elements and the second argument is an object. The object is list of products and their prices. All the <li>elements will have text containing a name of a product.The function should check the price of each product mentioned, calculate and return the total price.

Example:

<ul>
    <li>oreos<li/>
    <li>milk<li/>
<ul/>
let products = {
    oreos: 20,
    milk:  17,
    bread: 12,
    doritos: 10
}

I have tried using a for in/of loop to go through the products object and match it to the <li> using .innerText but am unsure of how to go about doing it.

Please help out

I need to write a function that takes in 2 arguments, the first argument is a list of <li> elements and the second argument is an object. The object is list of products and their prices. All the <li>elements will have text containing a name of a product.The function should check the price of each product mentioned, calculate and return the total price.

Example:

<ul>
    <li>oreos<li/>
    <li>milk<li/>
<ul/>
let products = {
    oreos: 20,
    milk:  17,
    bread: 12,
    doritos: 10
}

I have tried using a for in/of loop to go through the products object and match it to the <li> using .innerText but am unsure of how to go about doing it.

Please help out

Share Improve this question asked Oct 8, 2019 at 13:47 muhammadmuhammad 2552 silver badges14 bronze badges 2
  • 5 can you add the for in/of loop you tried ? – Taki Commented Oct 8, 2019 at 13:48
  • Rather than going through the products object you should go through your list of <li>s, since looking each text in the products object should be faster – Ayrton Commented Oct 8, 2019 at 13:50
Add a ment  | 

8 Answers 8

Reset to default 5

What you can do is that, you can use the following function:

let totalPrice = (priceList, products) => {
return products.reduce((total, elem) => {
    total += priceList[elem.innerText];
    return total;
}, 0)

}

This function iterates on list of products using Array.reduce and adds the list of product prices and returns the total.

You should checkout Array.reduce() for more clarity.

Here's what your function could look like:

  1. Iterate over all list items
  2. Get the text content of the item
  3. look up the price in the products object by using the text content as key
  4. add to the total
  5. return the total

I used Array.from() and Array.prototype.reduce() to achieve this all in one go. Of course you'd need a distinct class or even better an ID on the list instead of simply selecting all list items on the page.

let products = {
    oreos: 20,
    milk:  17,
    bread: 12,
    doritos: 10
}

function getTotal(listElements, productPrices) {
  var total = Array.from(listElements).reduce(function(total, listItem) {
    total += productPrices[listItem.textContent] || 0;
    return total;
  }, 0);
  return total;
}

console.log(getTotal(document.querySelectorAll('li'), products));
<ul>
    <li>oreos</li>
    <li>milk</li>
</ul>

Loop through the li elements, use their innerText as the key to lookup the price, sum them, and you're good:

let total = 0;
document.querySelectorAll('li').forEach(item => {
  total += products[item.innerText];
});

There are other forms of this, and little additions you could include (such as checking that the item actually exists in the products array first), but that's the basic idea.

You can add an id, let's say "list" to your <ul>, then do something like this:

let list = document.getElementById("list");
let totals = {};

for(let key of products) {
    totals[key] = 0;
}

for(let i = 0; i < list.children.length; i++) {
    let child = list.children[i];

    let text = child.textContent;

    if(totals.hasOwnProperty(text)) {
        totals[text]++;
    }
}

let fullPrice = 0;

for(let key of products) {
    fullPrice += products[key] * totals[key];
}

console.log(fullPrice);

The code does the following:

  1. It creates a totals object, which will count the occurrences of each existing product in your products object.
  2. Then, it gets your <ul> element, and loops through its <li> children elements, taking the text of each <li> and looking it up in the totals object.
  3. If the product exists, it increases the count.
  4. Lastly, it calculates the full, final price by multiplying the totals with the prices.

PS: This code assumes there will be only <li> elements inside your list, and that each <li> holds only text.

You fist need to fix your end-tags; the slash es before the final tag name.

Second, you can reduce all your list values by grabbing their text value and looking them up in the product list. You can use Array.from to translate a NodeList into an array so that you can call Array.prototype.reduce.

const products = {
    oreos: 20,
    milk:  17,
    bread: 12,
    doritos: 10
}

let total = calculateTotal(document.querySelector('ul.items'), products)

console.log(`Total = ${total}`)

function calculateTotal(ul, products) {
  return Array.from(ul.querySelectorAll('li'))
    .reduce((sum, li) => sum + products[li.textContent] || 0, 0)
}
<ul class="items">
    <li>oreos</li>
    <li>milk</li>
</ul>

You can try with querySelectorAll() and Array.prototype.reduce().

Please Note: You are closing the elements in the wrong way (<li/>, <ul/>) which will create unexpected markup, should be </li>, </ul>.

let products = {
    oreos: 20,
    milk:  17,
    bread: 12,
    doritos: 10
};
function getTotal(li, prod){
  return Array.from(li).reduce((a,c) => a + prod[c.textContent], 0);
}
console.log(getTotal(document.querySelectorAll('li'), products));
<ul>
    <li>oreos</li>
    <li>milk</li>
</ul>

To put you in the right direction (untested):

From: https://www.sitepoint./munity/t/looping-through-li-elements-in-ul/6049/2 and Check if a key exists inside a json object

<ul id="foo">
  <li>First</li>
  <li>Second</li>
  <li>Third</li>
</ul>

var ul = document.getElementById("foo");
var items = ul.getElementsByTagName("li");
for (var i = 0; i < items.length; ++i) {
  // do something with items[i], which is a <li> element
  if((items[i] in products)) alert("yeah");
}

Read this also: Looping through list items with jquery

  • This should put you in the right direction (may even work out of the box).

Trust this helps.

function getPrice()
{
    let products = {
        oreos: 20,
        milk:  17,
        bread: 12,
        doritos: 10
    }

    var items = document.getElementsByTagName("li");
    var price = 0;

    for (i = 0; i < items.length; i++) {
        var item = items[i];
        var val = parseFloat(products[item.innerHTML]);
        price += val;    
    }

    alert("Total price is: " + String(price));
}

You can then hook the function getPrice to the onclick property of a button to see the result. You may want to give your lists a class, or give the ul an id, so that getPrice doesn't return all the lists on your HTML page.

本文标签: javascriptHow to count and add the values of keys in a objectStack Overflow