You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript嵌套过滤器问题:过滤时原始数据被修改需保留

问题描述

我想在JavaScript中实现一个嵌套过滤器,但过滤数组时原始数据会被修改,我需要保留原始数据以便后续移除过滤器。

我的代码如下:

let result = companies;
result.map((item, i) => {
      let rows = [...result[i].table.table_rows].filter((item3) => {
         return Object.keys(item3).some(i => item3[i][key] === value[key]);
      });
                  
      result[i].table.table_rows = [...rows];
      return result[i];
   });
arrayFilter(result);

数据结构:

{
  "companies": [
    {
      "company": {
        "name": "company 1"
      },
      "table": {
        "table_rows": [
          {
            "cells": {
              "product_name": "prod1",
              "pa_size": "12"
            }
          },
          {
            "cells": {
              "product_name": "prod2",
              "pa_size": "15"
            }
          }
        ]
      }
    },
    {
      "company": {
        "name": "company 2"
      },
      "table": {
        "table_rows": [
          {
            "cells": {
              "product_name": "prod2-1",
              "pa_size": "12"
            }
          },
          {
            "cells": {
              "product_name": "prod2-2",
              "pa_size": "18"
            }
          }
        ]
      }
    }
  ]
}

我试过多种方法都没解决问题。


解决方案

你的问题核心是直接操作了原始数据的引用,导致原始数据被修改。要保留原始数据,必须在过滤时创建数据的副本,而非直接修改原对象。

问题分析

  1. let result = companies; 是引用赋值,result和companies指向同一块内存,操作result本质就是修改原始的companies。
  2. 即便用[...result[i].table.table_rows]复制了行数组,但result[i].table还是原始对象的引用,修改table_rows属性依然会改动原始数据。

修复后的代码

方法1:用结构化克隆创建深拷贝

// 先深克隆原始数据,彻底隔离原数据
const result = structuredClone(companies);
result.map(item => {
  const filteredRows = item.table.table_rows.filter(row => {
    return Object.keys(row).some(keyInRow => row[keyInRow][key] === value[key]);
  });
  // 因为已经克隆过item,修改table_rows不会影响原数据
  item.table.table_rows = filteredRows;
  return item;
});
arrayFilter(result);

方法2:手动逐层创建副本(兼容旧环境)

如果你的环境不支持structuredClone,可以手动逐层复制对象:

const result = companies.map(company => {
  return {
    // 复制company的第一层属性
    ...company,
    // 复制table对象并替换过滤后的table_rows
    table: {
      ...company.table,
      table_rows: company.table.table_rows.filter(row => {
        return Object.keys(row).some(keyInRow => row[keyInRow][key] === value[key]);
      })
    }
  };
});
arrayFilter(result);

关键要点

  • 永远不要直接操作原始数据的引用,处理前必须创建副本。
  • 嵌套对象需要深拷贝(structuredClone或手动逐层复制),浅拷贝(如...扩展运算符)只能处理第一层。
  • map本身会返回新数组,但如果内部修改原对象属性,依然会污染原始数据,所以要确保每个层级都是新对象。

内容的提问来源于stack exchange,提问作者Alireza Bagheri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 22:42:24