如何比较两个对象数组并获取公共对象

Posted

技术标签:

【中文标题】如何比较两个对象数组并获取公共对象【英文标题】:How to compare two array of object and get common objects 【发布时间】:2018-01-09 06:58:49 【问题描述】:

大家好,我有两个数组

var elements = [
        "id": "id_1",
        "type": "input",
        "businesstype":  "type": "text" 
    ,
    
        "type": "label",
        "id": "id_234"
    ,
    
        "id": "id_16677",
        "type": "div",
    ,
    
        "id": "id_155",
        "type": "input",
        "businesstype":  "type": "password" 
    
]

var filterArray=[type:'input',businesstype:type:'text',type:'div']

想要共同的对象

var output = [
        "id": "id_1",
        "type": "input",
        "businesstype":  "type": "text" 
    ,
    
        "id": "id_16677",
        "type": "div",
    
]

如何比较这两个对象以从元素中获取相等的对象。

【问题讨论】:

【参考方案1】:

(因为你标记了 Ramda)

Ramda 已经有许多有用的(对象)比较函数,您可以使用这些函数使过滤器更易于阅读。 (即:equals 和其他在后台使用它的函数,例如 contains

例如,你可以这样写:

const elements=[id:"id_1",type:"input",businesstype:type:"text",type:"label",id:"id_234",id:"id_16677",type:"div",id:"id_155",type:"input",businesstype:type:"password"];
const filterArray=[type:'input',businesstype:type:'text',type:'div'];

// Describes how to define "equality"
// i.e.: elements are equal if type and businesstype match
// e.g.: pick(["a", "b"],  a: 1, b: 2, c: 3) ->  a: 1, b: 2
const comparisonObjectFor = pick(["type", "businesstype"]);

// Compares an object's comparison representation to another object
const elEquals = compose(whereEq, comparisonObjectFor);

// Creates a filter method that searches an array
const inFilterArray = matchElements => el => any(elEquals(el), matchElements);

// Run the code on our data
filter(inFilterArray(filterArray), elements);

运行示例here

我认为这不一定是最好的解决方案(就可重用性、可读性而言),但我建议您不要内联深度对象/数组比较方法,因为:

    您可能会多次使用它们 如果没有正确的名称和文档,它们很难理解/预测 由于其复杂性,它们很容易出现(小)错误

换句话说:既然你已经标记了 lodash 和 Ramda,我可以安全地建议使用经过良好测试、使用良好的库来比较你的对象

【讨论】:

【参考方案2】:

您可以对嵌套对象使用递归方法对其进行过滤。

const isObject = o => o && typeof o === 'object',
      isEqual = (f, o) =>
          isObject(o) && Object.keys(f).every(k =>
              isObject(f[k]) && isEqual(f[k], o[k]) || o[k] === f[k]
          );

var elements = [ id: "id_1", type: "input", businesstype:  type: "text"  ,  type: "label", id: "id_234" ,  id: "id_16677", type: "div" ,  id: "id_155", type: "input", businesstype:  type: "password"  ],
    filterArray = [ type: 'input', businesstype:  type: 'text'  ,  type: 'div' ],
    result = elements.filter(o => filterArray.some(f => isEqual(f, o)));

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

【讨论】:

【参考方案3】:

如果您的 filterArray 在其层次结构中没有其他对象,您可以使用此解决方案 - 请参阅下面的演示:

var elements=[id:"id_1",type:"input",businesstype:type:"text",type:"label",id:"id_234",id:"id_16677",type:"div",id:"id_155",type:"input",businesstype:type:"password"],filterArray=[type:"input",businesstype:type:"text",type:"div"];

var result = elements.filter(function(e) 
  return filterArray.some(function(f) 
    return Object.keys(f).every(function(k) 
      return e.hasOwnProperty(k) && Object.keys(f[k]).every(function(n) 
        return e[k][n] == f[k][n];
      );
    );
  );
);

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

【讨论】:

以上是关于如何比较两个对象数组并获取公共对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在 es6 中仅比较和过滤两个对象数组中不匹配的数组

如何比较两个数组并通过完整迭代删除重复的对象

与第一个对象进行比较时,如何获取第二个对象数组的所有属性?

js 如何比较两个对象相等

比较两个对象数组并在新数组中返回匹配值

如何获取对象数组并减少它,以便组合重复对象键处的数据?