【问题标题】:How to use `Array.prototype.filter` to remove one item from an array?如何使用 `Array.prototype.filter` 从数组中删除一项?
【发布时间】:2021-12-28 03:37:28
【问题描述】:

我不太了解此功能,例如您过滤掉了什么以及它的工作方式...有人可以帮我解释一下吗?我是一个初学者,我需要你的帮助!顺便说一句,非常感谢!

功能:

removeFromCart =(product) => {
  const cartItems = this.state.cartItems.slice()
  this.setState({
    cartItems: cartItems.filter((x)=>x.id!==product.id)
  })
}

【问题讨论】:

  • 只允许id不匹配的人,如果匹配则不包括在内,比如酒精只允许age>18如果不匹配则不允许filtered out
  • 谢谢,我现在有点明白了,但我的函数不起作用,因为没有定义 id。你能帮我解决这个问题吗?链接:codesandbox.io/s/redux-shop-cart-forked-19huj?file=/src/…
  • 仅供参考:类似于我们为您的addToCart 函数所做的搜索,您需要首先检查是否有要删除的项目,并且只删除和更新状态如果有,否则你让应用程序和 React 工作并触发重新渲染。
  • @naha 检查我更新的答案。您没有将产品传递给 remove 函数。

标签: javascript reactjs filter


【解决方案1】:

Array.prototype.filter 需要一个返回布尔值的回调。

如果回调返回true,则将元素推送到新数组中,如果返回false,则不会推送元素。

const cartItems = this.state.cartItems.slice() 创建一个新数组并且可以被删除,因为filter 无论如何都会创建一个新数组。


cartItems.filter((x)=>x.id!==product.id)

如果我们考虑上面的 sn-p,返回值为 x.id!==product.id,因为如果 id 匹配,x.id !== product.id 将评估为 false,返回 false 将删除产品。


更新:

您似乎也有将产品传递给函数的问题。修复了这个问题,这是更新后的沙箱:

<button className="button" onClick={() => props.removeFromCart(item)}>
  Remove
</button>

【讨论】:

  • 我们需要做({...this.state, cartItems: prevState.})
  • @AshishKamble 在类组件中,setState 合并更新的属性而不覆盖。所以,不需要。
【解决方案2】:

这是该代码的较长版本,您可能会感到困惑,因为您的版本有很多快捷方式和错误的变量名。 (cmets)

removeFromCart = (product) => {
  const cartItems = this.state.cartItems.filter((item) => {
     return item.id !== product.id;
  });


  this.setState({
    cartItems: t
  })
}

让我们知道这一点:

const cartItems = this.state.cartItems.slice()

首先,你不需要这个,因为filter 已经返回了一个新数组 通常您使用slice 创建该数组的副本(部分)(通常我们在其上传递参数,我很少看到开发人员将其用作“克隆”函数的用法。You can read more about it here

  const cartItems = this.state.cartItems.filter((item) => {
     return item.id !== product.id;
  });

为此,我将您的变量 x 重命名为 item 以使其更易于理解。由于cartItems 是一个数组,因此该函数将遍历每个项目,然后创建一个新数组,其中项目 ID 与产品 ID (return item.id !== product.id) 不同。 Read more about filters here

  this.setState({
    cartItems
  })

你传递新创建的cartItems 来更新你的状态。

【讨论】:

    【解决方案3】:

    在您的代码中,Array.prototype.slice 函数用于创建状态 cartItems 的副本,它是一个数组。 Array.prototype.filter 函数用于过滤数组并仅返回与传递给过滤函数的回调函数中的测试条件匹配的项。

    确切地说,您将cartItems 数组设置为等于一个数组,该数组仅包含id 不同于作为removeFromCart 函数参数的产品传递的id 的项目。

    【讨论】:

      【解决方案4】:

      有两点需要注意。

      1. 首先,我们使用javascript 的slice() 方法获取数组的浅拷贝。这样做是为了

      我们不会改变原始状态

      (这是 React 的基本原则)

      const cartItems = this.state.cartItems.slice(); // We have the copy of original state 
      

      我们可以使用 ES6 扩展运算符实现相同的效果(在 React 中推荐)

      const cartItems = [...this.state.cartItems];// This does the same what slice() does
      
      1. 第二部分是过滤方法中的逻辑,它是一个高阶函数。

        cartItems.filter((x)=>x.id!==product.id)
        

      对于数组中的每个项目(数组中的每个对象),此回调函数都会运行

      (x)=>x.id!==product.id
      

      在每次迭代中检查item.id(即当前对象的id)是否不等于所选的id。因此,所有项目都被过滤并显示,除了产品 ID 与项目 ID 匹配的项目(DOM 中未显示此项目)之外。

      最后,您正在使用过滤后的项目更新您的状态,因此您的功能按预期工作:)

      建议您了解高阶函数,例如 map()filter()reduce(),因为它们在 React 和 Javascript 框架中被大量使用,因为您才刚刚开始。

      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
      

      【讨论】:

      • 第一部分完全没有必要,不推荐使用数组扩展语法。它更易于使用。
      • 我尊重你说的,但我不同意。我相信传播运算符更受推荐:) 我一直在我的所有项目中使用它。这些都是我的项目,我在 React 上工作了很多 github.com/emmeiwhite?tab=repositories
      • 你似乎没有抓住重点。 OP 不需要传播或切片,因为 filter 无论如何都会创建一个新数组。
      • 我只是在解释了slice() 的作用后推荐它:)
      【解决方案5】:

      在您的Cart.js 中,您必须更改调用函数并传递项目props.removeFromCart(item)}

      <button
        className="button"
        onClick={() => props.removeFromCart(item)}
      >
        Remove
      </button>
      

      App.js 中,保持不变或,

        removeFromCart = (product) => {
          //const cartItems = this.state.cartItems.slice();
          this.setState((prevState) => ({
             cartItems: prevState.cartItems.filter((x) => x._id !== product._id)
          }));
        };
      

      这正是需要做的事情,但它会删除选定的购物车元素

      【讨论】:

        猜你喜欢
        • 2021-10-19
        • 2019-09-21
        • 2020-11-16
        • 1970-01-01
        • 2021-10-09
        • 2013-06-04
        • 2022-06-25
        • 2016-09-07
        • 2013-12-02
        相关资源
        最近更新 更多