【问题标题】:compare two object arrays by javascript keys通过 javascript 键比较两个对象数组
【发布时间】:2022-01-07 19:24:46
【问题描述】:

我正在使用 javascript 我有两种安排,例如:

const arr1 = [
    { url: 1, 'title': 'A', 'title2': 'A2' },
    { url: 2, 'title': 'B', 'title2': 'B2' },
    { url: 3, 'title': 'C', 'title2': 'C2' },
    { url: 4, 'title': 'D', 'title2': 'D2' },
    { url: 5, 'title': 'E', 'title2': 'E2' },
]

const arr2 = [
    { url: 1, 'title': 'A', 'title2': 'J2' },
    { url: 2, 'title': 'J', 'title2': 'B2' },
    { url: 3, 'title': 'C', 'title2': 'C2' },
    { url: 4, 'title': 'D', 'title2': 'D2' },
    { url: 5, 'title': 'K', 'title2': 'E2' },
]

我想从第二个数组中获取那些与titletitle2 不同的对象

我尝试了以下方法,但对我不起作用,我在哪里迷路了?

const res = arr2.filter((page1) => !arr1.some(page2 => page1.title === page2.title || page2.title2 == page1.title2 ))

示例的预期结果是这样的:

[{ url: 1, 'title': 'A', 'title2': 'J2' },{"url":2,"title":"J","title2":"B2"},{"url":5,"title":"K","title2":"E2"}]

【问题讨论】:

  • 您不是在寻找网址。

标签: javascript arrays ecmascript-6


【解决方案1】:

如果我理解您的目标,那就是首先匹配 URL,然后找出标题是否存在差异。如果这是正确的,这会让你到达那里。

const res = arr2.filter(page1 => {
  // find URL match
  let page2 = arr1.find(f => f.url === page1.url) 
  return !page2 || page2.title != page1.title || page2.title2 != page1.title2;
})

const arr1 = [
    { url: 1, 'title': 'A', 'title2': 'A2' },
    { url: 2, 'title': 'B', 'title2': 'B2' },
    { url: 3, 'title': 'C', 'title2': 'C2' },
    { url: 4, 'title': 'D', 'title2': 'D2' },
    { url: 5, 'title': 'E', 'title2': 'E2' },
]

const arr2 = [
    { url: 1, 'title': 'A', 'title2': 'J2' },
    { url: 2, 'title': 'J', 'title2': 'B2' },
    { url: 3, 'title': 'C', 'title2': 'C2' },
    { url: 4, 'title': 'D', 'title2': 'D2' },
    { url: 5, 'title': 'K', 'title2': 'E2' },
]

const res = arr2.filter(page1 => {
  // find URL match
  let page2 = arr1.find(f => f.url === page1.url) 
  return !page2 || page2.title != page1.title || page2.title2 != page1.title2;
})
console.log(res)

【讨论】:

  • 答案是正确的,和我的很相似,请您解释一下我的解决方案有什么问题,以免犯错误并学习
  • 在您的尝试中,您在比较标题之前没有先找到相应的匹配网址。
【解决方案2】:

您可以使用url 作为键从对象中收集来自array1 的所有对象,并通过检查titletitle2 过滤第二个数组。

const
    array1 = [{ url: 1, 'title': 'A', 'title2': 'A2' }, { url: 2, 'title': 'B', 'title2': 'B2' }, { url: 3, 'title': 'C', 'title2': 'C2' }, { url: 4, 'title': 'D', 'title2': 'D2' }, { url: 5, 'title': 'E', 'title2': 'E2' }],
    array2 = [{ url: 1, 'title': 'A', 'title2': 'J2' }, { url: 2, 'title': 'J', 'title2': 'B2' }, { url: 3, 'title': 'C', 'title2': 'C2' }, { url: 4, 'title': 'D', 'title2': 'D2' }, { url: 5, 'title': 'K', 'title2': 'E2' }],
    keys = ['title', 'title2'],
    urls = Object.fromEntries(array1.map(o => [o.url, o])),
    result = array2.filter(o => keys.some(k => o[k] !== urls[o.url][k]));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案3】:

    最简单的方法是将一个映射到一个查找并循环第二个。

    const arr1 = [
        { url: 1, 'title': 'A', 'title2': 'A2' },
        { url: 2, 'title': 'B', 'title2': 'B2' },
        { url: 3, 'title': 'C', 'title2': 'C2' },
        { url: 4, 'title': 'D', 'title2': 'D2' },
        { url: 5, 'title': 'E', 'title2': 'E2' },
    ];
    
    const arr2 = [
        { url: 1, 'title': 'A', 'title2': 'J2' },
        { url: 2, 'title': 'J', 'title2': 'B2' },
        { url: 3, 'title': 'C', 'title2': 'C2' },
        { url: 4, 'title': 'D', 'title2': 'D2' },
        { url: 5, 'title': 'K', 'title2': 'E2' },
    ];
    
    const arr1MapByUrl = arr1.reduce((acc, data) => {
      acc[data.url] = data;
      return acc;
    }, {});
    
    const results = arr2.filter(data => {
      const org = arr1MapByUrl[data.url];
      return !org || data.title !== org.title || data.title2 !== org.title2;
    });
    
    console.log(results);

    如果您不想对要检查的键进行硬编码,可以使用 some() 遍历它们并进行比较。

    const arr1 = [
        { url: 1, 'title': 'A', 'title2': 'A2' },
        { url: 2, 'title': 'B', 'title2': 'B2' },
        { url: 3, 'title': 'C', 'title2': 'C2' },
        { url: 4, 'title': 'D', 'title2': 'D2' },
        { url: 5, 'title': 'E', 'title2': 'E2' },
    ];
    
    const arr2 = [
        { url: 1, 'title': 'A', 'title2': 'J2' },
        { url: 2, 'title': 'J', 'title2': 'B2' },
        { url: 3, 'title': 'C', 'title2': 'C2' },
        { url: 4, 'title': 'D', 'title2': 'D2' },
        { url: 5, 'title': 'K', 'title2': 'E2' },
    ];
    
    const arr1MapByUrl = arr1.reduce((acc, data) => {
      acc[data.url] = data;
      return acc;
    }, {});
    
    const results = arr2.filter(data => {
      const org = arr1MapByUrl[data.url];
      return !org || Object.entries(data).some(([key, value]) => org[key] !== value);
    });
    
    console.log(results);

    【讨论】:

      【解决方案4】:

      根据arr1构建一个对象来跟踪标题,并使用同一对象过滤arr2

      const arr1=[{url:1,title:"A",title2:"A2"},{url:2,title:"B",title2:"B2"},{url:3,title:"C",title2:"C2"},{url:4,title:"D",title2:"D2"},{url:5,title:"E",title2:"E2"}];
      
      const arr2=[{url:1,title:"A",title2:"J2"},{url:2,title:"J",title2:"B2"},{url:3,title:"C",title2:"C2"},{url:4,title:"D",title2:"D2"},{url:5,title:"K",title2:"E2"}];
      
      const track = {};
      arr1.forEach(({ url, title, title2 }) =>
        Object.assign(track, { [url]: { [title]: title2 } })
      );
      
      const results = arr2.filter(
        ({ url, title, title2 }) => track?.[url]?.[title] !== title2
      );
      
      console.log(results)

      【讨论】:

        猜你喜欢
        • 2013-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-05
        • 1970-01-01
        • 2023-03-31
        • 2019-08-02
        相关资源
        最近更新 更多