【问题标题】: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",
    }
]

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

【问题讨论】:

    标签: javascript arrays node.js lodash ramda.js


    【解决方案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

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

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

    换句话说:既然你已经标记了 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;}

        【讨论】:

          猜你喜欢
          • 2021-03-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多