使用多个条件检查数组中的任意两个对象是否相等

Check any two object in an array are Equal using multiple Conditions

在我的 angular 项目中,我有一个类似

的数据源
  [
    {id: "1", name: "John", age: "23", gender:"M", Role: "Student"},
    {id: "2", name: "Smith", age: "24", gender:"M", Role: "Teacher"},
    {id: "3", name: "Jeff", age: "23", gender:"M", Role: "Student"},
    {id: "4", name: "Ronald", age: "25", gender:"M", Role: "Teacher"},
    {id: "5", name: "Ronak", age: "23", gender:"M", Role: "Student"}
]

我需要根据多个条件检查任意两行或多行数据是否相同。例如:如果任意两行具有相同的年龄、性别和角色,则 return 他们的姓名

所以预期输出将是

[John,Jeff, Ronak]

因为他们有相同的年龄、性别和角色 其他

[]

我尝试对数组进行分组,但没有找到任何使用多个条件对其进行分组的解决方案,然后尝试了嵌套循环,但似乎效率低下,结果不如预期。

您可以为想要的属性取一个连接键,收集组的名称和return具有三个或更多项目的组中的所有名称。

var data = [{ id: "1", name: "John", age: "23", gender: "M", Role: "Student" }, { id: "2", name: "Smith", age: "24", gender: "M", Role: "Teacher" }, { id: "3",  name: "Jeff", age: "23", gender: "M", Role: "Student" }, { id: "4", name: "Ronald", age: "25", gender: "M", Role: "Teacher" }, { id: "5", name: "Ronak", age: "23", gender: "M", Role: "Student" }],
    keys = ['age', 'gender', 'Role'],
    groups = data.reduce((r, o) => {
        const key = keys.map(k => o[k]).join('|');
        r[key] = r[key] || [];
        r[key].push(o.name);
        return r;
    } , {}),
    result = Object.values(groups).flatMap(a => a.length >= 3 ? a : []);

console.log(result);
console.log(groups);

我会使用辅助函数对数据进行适当分组,并向其传递一个从重要数据生成唯一键的函数。像这样:

// Utility functions
const groupBy = (fn) => (xs) => 
  xs .reduce ((a, x) => ({... a, [fn(x)]: [... (a [fn (x)] || []), x]}), {})

const getProp = (obj) => (prop) =>
  obj [prop]

// Helper function
const makeKey = (props) => (record) =>
  props .map (getProp (record)) .join('|')

// Main function
const multipleMatch = (props) => (data) => 
  Object 
    .values (groupBy (makeKey(props)) (data)) 
    .filter (arr => arr.length > 1)

// Demos
const data = [{id: "1", name: "John", age: "23", gender:"M", Role: "Student"}, {id: "2", name: "Smith", age: "24", gender:"M", Role: "Teacher"}, {id: "3", name: "Jeff", age: "23", gender:"M", Role: "Student"}, {id: "4", name: "Ronald", age: "25", gender:"M", Role: "Teacher"}, {id: "5", name: "Ronak", age: "23", gender:"M", Role: "Student"}]
console .log (multipleMatch (['age', 'gender', 'Role']) (data))

// Changing the age of one to get two different shared groups
const data2 = [{id: "1", name: "John", age: "23", gender:"M", Role: "Student"}, {id: "2", name: "Smith", age: "24", gender:"M", Role: "Teacher"}, {id: "3", name: "Jeff", age: "23", gender:"M", Role: "Student"}, {id: "4", name: "Ronald", age: "24", gender:"M", Role: "Teacher"}, {id: "5", name: "Ronak", age: "23", gender:"M", Role: "Student"}]
console .log (multipleMatch (['age', 'gender', 'Role']) (data2))

makeKeygetProp 函数可以很容易地内联。但是打出groupBy好像问题就清楚多了

这个returns对象数组的数组。如果你只想要他们的名字,很容易加上 .map (group => group .map (record => record .name)),或者用 .flatMap 替换最初的 .map,你会得到一个单一的数组,代价是失去报告的潜力多个组。