Novice coder question – JS User-generated shopping list – How to update number property of list objects and avoid duplicates

huangapple go评论60阅读模式
英文:

Novice coder question - JS User-generated shopping list - How to update number property of list objects and avoid duplicates

问题

以下是您要翻译的代码部分:

e.g. if a user submits "tacos" twice, instead of having two lines, each containing "tacos", I want to have one line with "tacos x 2". Question 2 - is it possible to create a variable that selects every item in an array except another variable? e.g.

for (let i = 0; i < items.length; i++) {
  let j = !i;
}

(I am aware the above code is incorrect, I included it only to illustrate my question)

Thank you in advance.

// key function out of context
if (!items.includes(item.text)) {
  items.push(item);
} else {
  items.item.number =+1
}

如果您有其他问题或需要进一步的帮助,请随时告诉我。

英文:

e.g. if a user submits "tacos" twice, instead of having two lines, each containing "tacos", I want to have one line with "tacos x 2". Question 2 - is it possible to create a variable that selects every item in an array except another variable? e.g.

for (let i = 0; i &lt; items.length; i++)
{let j = !i;
}

(I am aware the above code is incorrect, I included it only to illustrate my question)

Thank you in advance.

 // key function out of context
 if (!items.includes(item.text)) {
 items.push(item);
 } else {
  items.item.number =+1
 }


 //entire html file with script including key function in context

 &lt;!DOCTYPE html&gt;
 &lt;html lang=&quot;en&quot;&gt;
 &lt;head&gt;
 &lt;meta charset=&quot;UTF-8&quot;&gt;
 &lt;title&gt;LocalStorage&lt;/title&gt;
 &lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot;&gt;
 &lt;/head&gt;
 &lt;body&gt;


 &lt;div class=&quot;wrapper&quot;&gt;
 &lt;h2&gt;LOCAL TAPAS&lt;/h2&gt;
 &lt;p&gt;&lt;/p&gt;
 &lt;ul class=&quot;plates&quot;&gt;
  &lt;li&gt;Loading Tapas...&lt;/li&gt;
 &lt;/ul&gt;
 &lt;form class=&quot;add-items&quot; autocomplete=&quot;off&quot;&gt;
  &lt;input type=&quot;text&quot; name=&quot;item&quot; placeholder=&quot;Item Name&quot; required&gt;
  &lt;input type=&quot;submit&quot; value=&quot;+ Add Item&quot;&gt;
 &lt;/form&gt;
 &lt;button type=&quot;reset&quot; value=&quot;reset&quot;&quot;&gt;clear all&lt;/button&gt;
 &lt;button class=&quot;select&quot;&gt;Select all&lt;/button&gt;
 &lt;/div&gt;

 &lt;script&gt;

 const addItems = document.querySelector(&#39;.add-items&#39;);
 const itemsList = document.querySelector(&#39;.plates&#39;);
 const selectAll = document.querySelector(&#39;.select&#39;);
 const items = [];
 const mySet = new Set();
 const userInput = document.querySelector(&#39;[type=&quot;text&quot;]&#39;);
 // add items to list

 // populate list with html

  function add(e) {
  e.preventDefault();
  console.dir(e.currentTarget)
  const text = e.currentTarget.item.value;

  const item = {
    text,
    done:false,
    number: 1,
  };

  console.dir(item)

  
 if (!items.includes(item.text)) {
 items.push(item);
 } else {
 items.item.number =+1
 }



  e.currentTarget.reset();

  itemsList.dispatchEvent(new CustomEvent(&#39;itemsUpdated&#39;))

  }

 function displayItems(item, i) {
 const html = items.map((item, i) =&gt; `
 &lt;li&gt;
 &lt;input type=&quot;checkbox&quot;&gt;
 &lt;label name=&quot;${item}&quot; id=&quot;${i}&quot;&gt;&lt;strong&gt;${item.text}&lt;/strong&gt; x${item.number}             &lt;/label&gt;
&lt;/li&gt;`).join(&#39;&#39;);

itemsList.innerHTML = html;

};






  addItems.addEventListener(&#39;submit&#39;, add)
 itemsList.addEventListener(&#39;itemsUpdated&#39;, displayItems)



 &lt;/script&gt;


 &lt;/body&gt;
 &lt;/html&gt;

答案1

得分: 0

问题出在于您如何检查item对象是否在items数组中。

由于数组的元素是对象,您需要修改检查的方式 - includesindexOf都不起作用。

您需要这样做:

let indx = items.findIndex(element => element.text === item.text);

array.findIndex允许您在数组中找到满足给定条件的元素。在这种情况下,您想根据名称查找特定产品。这就是为什么我们要执行element.text === item.text比较。

查看下面的更新示例,以查看它的运行方式。

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-js -->

const addItems = document.querySelector('.add-items');
const itemsList = document.querySelector('.plates');
const selectAll = document.querySelector('.select');
const items = [];
const mySet = new Set();
const userInput = document.querySelector('[type="text"]');
// add items to list
// populate list with html

function add(e) {
    e.preventDefault();
    const text = e.currentTarget.item.value;

    const item = {
        text,
        done:false,
        number: 1,
    };

    /* 这些是关键更改 */
    let indx = items.findIndex(element => element.text === item.text);

    if (indx < 0) {
        items.push(item);
    } else {
        items[indx].number += 1;
    }
    /* */

    e.currentTarget.reset();
    itemsList.dispatchEvent(new CustomEvent('itemsUpdated'))
}

function displayItems(item, i) {
    const html = items.map((item, i) => `
        <li>
            <input type="checkbox">
            <label name="${item}" id="${i}"><strong>${item.text}</strong> x${item.number}</label>
        </li>
    `).join('');

    itemsList.innerHTML = html;
};

addItems.addEventListener('submit', add)
itemsList.addEventListener('itemsUpdated', displayItems)

<!-- language: lang-html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>LocalStorage</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="wrapper">
        <h2>LOCAL TAPAS</h2>
        <p></p>
        <ul class="plates">
            <li>Loading Tapas...</li>
        </ul>
        <form class="add-items" autocomplete="off">
            <input type="text" name="item" placeholder="Item Name" required>
            <input type="submit" value="+ Add Item">
        </form>
        <button type="reset" value="reset">clear all</button>
        <button class="select">Select all</button>
    </div>
</body>
</html>

<!-- end snippet -->

**编辑** 还有一些小的语法错误更正:
- 在您的原始代码中,重置按钮的值是`value="reset"'"。我已经删除了额外的引号。
- 您对`item.number`的初始递增也是错误的 - 与`items.item.number =+1`不同,它应该是(如现在的那样)`items[indx].number += 1`。请注意是`+=`而不是`=+`。

<details>
<summary>英文:</summary>

The problem lies with how you&#39;re checking if your `item` object is in the `items` array.

Since the elements of your array are objects, you would need to modify that checkup - `includes` and `indexOf` won&#39;t work.

What you would need to do is:

let indx = items.findIndex(element => element.text === item.text);

[`array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) will let you find an element within an array which satisfies the given condition. In this case, you want to find a specific product by name. That&#39;s why we&#39;re doing the `element.text === item.text` comparison.
Check the updated example below, to see it in action.
&lt;!-- begin snippet: js hide: false console: false babel: false --&gt;
&lt;!-- language: lang-js --&gt;
const addItems = document.querySelector(&#39;.add-items&#39;);
const itemsList = document.querySelector(&#39;.plates&#39;);
const selectAll = document.querySelector(&#39;.select&#39;);
const items = [];
const mySet = new Set();
const userInput = document.querySelector(&#39;[type=&quot;text&quot;]&#39;);
// add items to list
// populate list with html
function add(e) {
e.preventDefault();
const text = e.currentTarget.item.value;
const item = {
text,
done:false,
number: 1,
};
/* these are the key changes */
let indx = items.findIndex(element =&gt; element.text === item.text);
if (indx &lt; 0) {
items.push(item);
} else {
items[indx].number += 1;
}
/* */
e.currentTarget.reset();
itemsList.dispatchEvent(new CustomEvent(&#39;itemsUpdated&#39;))
}
function displayItems(item, i) {
const html = items.map((item, i) =&gt; `
&lt;li&gt;
&lt;input type=&quot;checkbox&quot;&gt;
&lt;label name=&quot;${item}&quot; id=&quot;${i}&quot;&gt;&lt;strong&gt;${item.text}&lt;/strong&gt; x${item.number}&lt;/label&gt;
&lt;/li&gt;
`).join(&#39;&#39;);
itemsList.innerHTML = html;
};
addItems.addEventListener(&#39;submit&#39;, add)
itemsList.addEventListener(&#39;itemsUpdated&#39;, displayItems)
&lt;!-- language: lang-html --&gt;
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;title&gt;LocalStorage&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;wrapper&quot;&gt;
&lt;h2&gt;LOCAL TAPAS&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;
&lt;ul class=&quot;plates&quot;&gt;
&lt;li&gt;Loading Tapas...&lt;/li&gt;
&lt;/ul&gt;
&lt;form class=&quot;add-items&quot; autocomplete=&quot;off&quot;&gt;
&lt;input type=&quot;text&quot; name=&quot;item&quot; placeholder=&quot;Item Name&quot; required&gt;
&lt;input type=&quot;submit&quot; value=&quot;+ Add Item&quot;&gt;
&lt;/form&gt;
&lt;button type=&quot;reset&quot; value=&quot;reset&quot;&gt;clear all&lt;/button&gt;
&lt;button class=&quot;select&quot;&gt;Select all&lt;/button&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;!-- end snippet --&gt;
**EDIT** There were also minor syntax error edits:
- in your original code, your reset button had this as its value - `value=&quot;reset&quot;&quot;`. I&#39;ve removed the extra quote.
- your initial incrementing of `item.number` was also erroneous - instead of `items.item.number =+1` it should have been (as it is now) `items[indx].number += 1`. Note that it&#39;s `+=` and not `=+`. 
</details>

huangapple
  • 本文由 发表于 2023年2月10日 02:33:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75402989.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定