我有一个对象数组
[
{
id1: {
props1: 1,
props2: 2,
props3: 3
}
},
{
id2: {
props1: 1,
props2: 3,
props3: 4
}
},
{
id3: {
props1: 1,
props2: 2,
props3: 4
}
},
{
id4: {
props1: 2,
props2: 2,
props3: 3
}
},
{
id5: {
props1: 2,
props2: 2,
props3: 4
}
}]
我想互相比较元素(对象),以获得包含相同的props1
和props2
的所有两个对象
所以我的结果应该是
[
[
{
id1: {
props1: 1,
props2: 2,
props3: 3
}
},
{
id3: {
props1: 1,
props2: 2,
props3: 4
}
}
],
[
{
id4: {
props1: 2,
props2: 2,
props3: 3
}
},
{
id5: {
props1: 2,
props2: 2,
props3: 4
}
}
]
]
有没有办法在不使用2个for循环的情况下互相比较2个元素(对象)?当数组的大小很大时,我担心2 for循环解决方案的性能
答案 0 :(得分:0)
您可以对列表进行分组,然后获得至少包含2个元素的分组。
Object.defineProperty(Array.prototype, "groupBy", {
configurable: false,
writable: false,
value: function(expression) {
return Array.prototype.reduce.call(this, function(result, value, index, array) {
var key = expression.call(array, value, index, array);
if (!(key in result)) result[key] = [];
result[key].push(value);
return result;
}, {});
}
});
var groups = [{
props1: 1,
props2: 2,
props3: 3
},
{
props1: 1,
props2: 3,
props3: 4
},
{
props1: 1,
props2: 2,
props3: 4
},
{
props1: 2,
props2: 2,
props3: 3
}
].groupBy(x => `${x.props1}, ${x.props2}`);
console.log("All the groups: ");
console.log(groups);
console.log("Groups with at least 2 items: ");
console.log(Object.keys(groups).filter(key => groups[key].length > 1).map(key => groups[key]));
如果您绝对只想进行1次传递,则可以通过牺牲抽象来通过以下方式实现。
function groupArray(list, expression) {
var tempList = {};
return list.reduce(function(result, value, index, array) {
var key = expression.call(array, value, index, array);
if (!(key in tempList)) tempList[key] = [];
else result[key] = tempList[key];
tempList[key].push(value);
return result;
}, {});
}
var groups = groupArray([{
props1: 1,
props2: 2,
props3: 3
},
{
props1: 1,
props2: 3,
props3: 4
},
{
props1: 1,
props2: 2,
props3: 4
},
{
props1: 2,
props2: 2,
props3: 3
}
], x => `${x.props1}, ${x.props2}`);
console.log("All the groups with at least 2 elements: ");
console.log(groups);
答案 1 :(得分:0)
无耻的自我插入:我的图书馆blinq
对于有效执行这种转换非常方便。
const {
blinq,
deepComparer
} = window.blinq;
const data = [{
id1: {
props1: 1,
props2: 2,
props3: 3
}
},
{
id2: {
props1: 1,
props2: 3,
props3: 4
}
},
{
id3: {
props1: 1,
props2: 2,
props3: 4
}
},
{
id4: {
props1: 2,
props2: 2,
props3: 3
}
},
{
id5: {
props1: 2,
props2: 2,
props3: 4
}
}
]
const transformedData = blinq(data)
.selectMany(x => Object.entries(x))
.groupBy(([k, v]) => ({
props1: v.props1,
props2: v.props2
}), deepComparer)
.where(g => g.count() > 1)
.select(g => g
.select(x => Object.fromEntries([x]))
.toArray()
)
.toArray();
console.log(transformedData);
<script src="https://cdn.jsdelivr.net/npm/blinq"></script>