如何比较两个对象数组并获取公共对象
How to compare two array of object and get common objects
大家好,我有两个数组
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",
}
]
如何比较这两个对象以从元素中获得相等的对象。
您可以使用嵌套对象的递归方法对其进行过滤。
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; }
如果您的 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;}
(因为你标记了 Ramda)
Ramda 已经有许多有用的(对象)比较函数,您可以使用它们来使过滤器更容易阅读。 (即:equals
and other functions that use it under the hood, like 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
我认为这不一定是最好的解决方案(就可重用性、可读性而言),但我建议您 不要 内联深度 object/array比较方法自:
- 您可能会不止一次地使用它们
- 如果没有正确的名称和文档,它们很难 understand/predict
- 由于它们的复杂性,它们容易出现(小)错误
换句话说:既然你已经标记了 lodash 和 Ramda,我可以放心地建议 使用一个经过良好测试、使用良好的库来比较你的对象。
大家好,我有两个数组
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",
}
]
如何比较这两个对象以从元素中获得相等的对象。
您可以使用嵌套对象的递归方法对其进行过滤。
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; }
如果您的 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;}
(因为你标记了 Ramda)
Ramda 已经有许多有用的(对象)比较函数,您可以使用它们来使过滤器更容易阅读。 (即:equals
and other functions that use it under the hood, like 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
我认为这不一定是最好的解决方案(就可重用性、可读性而言),但我建议您 不要 内联深度 object/array比较方法自:
- 您可能会不止一次地使用它们
- 如果没有正确的名称和文档,它们很难 understand/predict
- 由于它们的复杂性,它们容易出现(小)错误
换句话说:既然你已经标记了 lodash 和 Ramda,我可以放心地建议 使用一个经过良好测试、使用良好的库来比较你的对象。