【问题标题】:Delete specific object with id删除具有 id 的特定对象
【发布时间】:2020-02-04 09:07:14
【问题描述】:

我有一个对象数组,我需要根据id删除一个完整的对象

输入:

 filters: [
    {
      key: "status",
      label: "En attente",
      value: "waiting",
      id: 0
    },
    {
      key: "dateDue[min]",
      label: "15/12/2019",
      value: "15/12/2019",
      id: 1
    },
    {
      key: "dateDue[max]",
      label: "02/02/2020",
      value: "02/02/2020",
      id: 2
    },
    {
      key: "bien",
      values: [
        {
          label: "Studio Bordeaux",
          value: 36,
          id: 3
        },
        {
          label: "Studio 2",
          value: 34,
          id: 184
        }
      ]
    },
    {
      key: "type",
      values: [
        {
          type: "receipts",
          label: "Loyer",
          value: "loyer",
          id: 4
        },
        {
          type: "receipts",
          label: "APL",
          value: "apl",
          id: 5
        },
        {
          type: "spending",
          label: "taxes",
          value: "taxes",
          id: 6
        }
      ]
    }
  ]

所以我创建了一个 removeItem 方法,其 id 必须在参数中删除

removeItem 方法:

removeItem = (e, id) => {
const { filters } = this.state;

const remove = _.reject(filters, el => {
  if (!_.isEmpty(el.values)) {
    return el.values.find(o => o.id === id);
  }
  if (_.isEmpty(el.values)) {
    return el.id === id;
  }
});
this.setState({
  filters: remove
});

};

我使用 lodash 让我的工作更轻松、更具体 _.reject 我的问题如下: 例如,我设法正确删除了经典对象

{
  key: "status",
  label: "En attente",
  value: "waiting",
  id: 0
}

但是我的方法不适用于以下形式的对象

   {
      key: "bien",
      values: [
        {
          label: "Studio Bordeaux",
          value: 36,
          id: 3
        },
        {
          label: "Studio 2",
          value: 34,
          id: 184
        }
      ]
    },

目前整个对象都被删除了,而不仅仅是值数组中的对象根据其 id 删除

Here is my codesandbox!

提前感谢您的帮助

编辑

我找到了一个 lodash (compact) 的解决方案,我在这里分享我的解决方案:

  removeIdFromCollection = id => {
    const { filters } = this.state;
    const newFilters = [];
    _.map(filters, filter => {
      if (filter.values) {
        const valuesTmp = _.compact(
          _.map(filter.values, value => {
            if (value.id !== id) return value;
          })
        );
        if (!_.isEmpty(valuesTmp)) {
          return newFilters.push({
            key: filter.key,
            values: valuesTmp
          });
        }
      }
      if (filter.id && filter.id !== id) return newFilters.push(filter);
    });
    return newFilters;
  };

  removeItem = id => e =>
    this.setState({
      filters: this.removeIdFromCollection(id)
    });

使用 lodash compact (_.compact(array)) 删除值 false、null、0、""、undefined 和 NaN

这是我更新的代码框

【问题讨论】:

标签: javascript reactjs lodash


【解决方案1】:

您需要分别过滤filters 数组和每个values。下面是一个递归函数,它将从过滤器数组和 values 属性中删除具有给定 id 的项目。

附言。这个例子没有使用 Lodash,因为我认为在这种情况下不需要它。

  removeIdFromCollection = (collection, id) => {
    return collection.filter(datum => {
      if (Array.isArray(datum.values)) {
        datum.values = this.removeIdFromCollection(datum.values, id);
      }

      return datum.id !== id;
    });
  }

  removeItem = (e, id) => {
    const { filters } = this.state;

    this.setState({
      filters: this.removeIdFromCollection(filters, id),
    });
  };

【讨论】:

    【解决方案2】:

    问题是对象的结构。为了统一,您需要为那个不方便的数组进行重构:

    // Example
    filters: [
    ...
    {
      key: "type",
      values: [
        {
          type: "receipts",
          label: "Loyer",
          value: "loyer",
          id: 4
        },
        ...
      ]
    ...
    }
    
    // could be
    
    filters: [
    ...
    {
     key: "type-receipts",
     label: "Loyer",
     value: "loyer",
     id: 4
    }
    ...
    ]
    
    

    在上面重复这个模式,这样你就可以像这样使用原生数组过滤器:

    const newFilters = filters.filter(v => v.id !== id);
    
    this.setState({
      filters: newFilters,
    });
    

    【讨论】:

      【解决方案3】:

      我找到了一个 lodash 的解决方案,我在这里与你分享:

        removeIdFromCollection = id => {
          const { filters } = this.state;
          const newFilters = [];
          _.map(filters, filter => {
            if (filter.values) {
              const valuesTmp = _.compact(
                _.map(filter.values, value => {
                  if (value.id !== id) return value;
                })
              );
              if (!_.isEmpty(valuesTmp)) {
                return newFilters.push({
                  key: filter.key,
                  values: valuesTmp
                });
              }
            }
            if (filter.id && filter.id !== id) return newFilters.push(filter);
          });
          return newFilters;
        };
      
        removeItem = id => e =>
          this.setState({
            filters: this.removeIdFromCollection(id)
          });
      

      这是我更新的代码框

      【讨论】:

        猜你喜欢
        • 2011-11-04
        • 1970-01-01
        • 1970-01-01
        • 2013-10-13
        • 2018-02-07
        • 1970-01-01
        • 1970-01-01
        • 2014-08-30
        • 2020-08-28
        相关资源
        最近更新 更多