使用多个条件检查数组中的任意两个对象是否相等
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))
makeKey
和 getProp
函数可以很容易地内联。但是打出groupBy
好像问题就清楚多了
这个returns对象数组的数组。如果你只想要他们的名字,很容易加上 .map (group => group .map (record => record .name))
,或者用 .flatMap
替换最初的 .map
,你会得到一个单一的数组,代价是失去报告的潜力多个组。
在我的 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))
makeKey
和 getProp
函数可以很容易地内联。但是打出groupBy
好像问题就清楚多了
这个returns对象数组的数组。如果你只想要他们的名字,很容易加上 .map (group => group .map (record => record .name))
,或者用 .flatMap
替换最初的 .map
,你会得到一个单一的数组,代价是失去报告的潜力多个组。