如何比较两个对象数组并获取常见对象

时间:2017-08-02 07:29:58

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

大家好我有两个阵列

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",
    }
]

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

3 个答案:

答案 0 :(得分:1)

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

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; }

答案 1 :(得分:1)

如果您的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;}




答案 2 :(得分: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. 由于其复杂性,他们容易出现(小)错误
  4. 换句话说:既然你已经标记了lodash和Ramda,我可以安全地建议使用经过良好测试的,使用良好的库来比较你的对象

相关问题