【问题标题】:Filter based on multiple unique values基于多个唯一值进行过滤
【发布时间】:2026-02-07 16:45:01
【问题描述】:

我正在尝试确定以下最佳方法。

我有两个数组,如下所示:

const a = [
{
  Employee: "00001",
  Seq: "01",
  ReportDate: "2021-03-10T00:00:00.000",
  ReportName: "test report",
},
{
  Employee: "00002",
  Seq: "01",
  ReportDate: "2020-03-10T00:00:00.000",
  ReportName: "test report 2",
},
];


const b = [
{
  Employee: "00001",
  EmplName: "William Apple",
  ReportDate: "2021-03-10T00:00:00.000",
  ReportName: "test report",
  Posted: "Y",
  Seq: "01",
},
{
  Employee: "00003",
  EmplName: "John Smith",
  ReportDate: "2021-03-10T00:00:00.000",
  ReportName: "test report 3",
  Posted: "Y",
  Seq: "01",
},
];

我想过滤掉数组“b”中不包含数组“a”中的一个对象中的所有 4 个确切值的任何内容。

所以,按照上面的例子,我会留下:

// from array 'b'
const c = [
{
  Employee: "00001",
  EmplName: "William Apple",
  ReportDate: "2021-03-10T00:00:00.000",
  ReportName: "test report",
  Posted: "Y",
  Seq: "01",
}
];

我已经研究了各种方法来做到这一点。我不能只检查对象是否相等,因为数组“a”将仅包含 4 个值/键,而数组“b”将包含更多/动态数量。

通过循环和多个 IF 语句使用 Filter 方法会是最好的方法吗?

【问题讨论】:

    标签: javascript arrays object filter


    【解决方案1】:
    const results = b.filter(bv => !!a.find(av => Object.keys(av).filter(ak => av[ak] === bv[ak]).length === Object.keys(av).length));
    
    console.log(results);
    

    这会将“b”数组过滤到仅在“a”中也有匹配项的那些元素。 “匹配”在此由“a”项中的所有键/值与“b”项中的所有相应键/值匹配来确定。 “b”项中无关的键被忽略。

    【讨论】:

      【解决方案2】:

      我会从循环代码中分离出精确对象匹配的测试,如下所示:

      const subObject = (a, b) => 
        Object .entries (a) .every (([k, v]) => b [k] == v)
      
      const matches = (xs, ys) => 
        ys .filter (y => xs .some (x => subObject (x, y)))
      
      const a = [{Employee: "00001", Seq: "01", ReportDate: "2021-03-10T00:00:00.000", ReportName: "test report"}, {Employee: "00002", Seq: "01", ReportDate: "2020-03-10T00:00:00.000", ReportName: "test report 2"}]
      const b = [{Employee: "00001", EmplName: "William Apple", ReportDate: "2021-03-10T00:00:00.000", ReportName: "test report", Posted: "Y", Seq: "01"}, {Employee: "00003", EmplName: "John Smith", ReportDate: "2021-03-10T00:00:00.000", ReportName: "test report 3", Posted: "Y", Seq: "01"}]
      
      console .log (matches (a, b))

      subObject 检查a 的每个属性是否在b 中具有相同的值。

      matches 使用它来根据第一个列表是否有某个元素是它的子对象来过滤第二个列表。

      结果都是非常简单的函数。虽然我们可以将 subObject 内联到 matches 中,但我认为它本身很有用,并且可以生成更好的代码。

      【讨论】:

        【解决方案3】:

        您可以使用.reduce 遍历a 的项目并将它们存储在Map 中,其中Employeekey,其他属性(Seq、ReportDate、ReportName)是value .

        之后,使用.filterb 获取项目,其中它们的Employee 存在于地图中并且其他三个属性匹配。

        const a = [
          { Employee: "00001", Seq: "01", ReportDate: "2021-03-10T00:00:00.000", ReportName: "test report" },
          { Employee: "00002", Seq: "01", ReportDate: "2020-03-10T00:00:00.000", ReportName: "test report 2" }
        ];
        const b = [
          { Employee: "00001", EmplName: "William Apple", ReportDate: "2021-03-10T00:00:00.000", ReportName: "test report", Posted: "Y", Seq: "01" },
          { Employee: "00003", EmplName: "John Smith", ReportDate: "2021-03-10T00:00:00.000", ReportName: "test report 3", Posted: "Y", Seq: "01" }
        ];
        
        const employeesMap = a.reduce((map,employee) => {
          const { Employee, ...attributes } = employee;
          map.set(Employee, attributes);
          return map;
        }, new Map);
        
        const res = b.filter(employee => {
          const { Employee, Seq, ReportDate, ReportName } = employee;
          const employeeFromA = employeesMap.get(Employee);
          return employeeFromA && 
            employeeFromA.Seq === Seq && 
            employeeFromA.ReportDate === ReportDate && 
            employeeFromA.ReportName === ReportName;
        });
        
        console.log(res);

        【讨论】:

        • 虽然对于大量输入,这可能比我的更有效,但您假设特定字段在记录中是唯一的。这在此处是否合理是一个很好的问题,但显然做出这样的假设不太普遍。