我通过一些属性为对象的自定义分组数组创建了一个自定义管道:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'groupBy'})
export class GroupByPipe implements PipeTransform {
transform(value: Array<any>, field: string): Array<any> {
const groupedObj = value.reduce((prev, cur)=> {
if(!prev[cur[field]]) {
prev[cur[field]] = [cur];
} else {
prev[cur[field]].push(cur);
}
return prev;
}, {});
return Object.keys(groupedObj).map(key => ({ key:key, value: groupedObj[key] }));
}
}
<div>
<h2>Group by department</h2>
<ul>
<li *ngFor="let group of employees | groupBy:'department'">Department{{group.key}}
<ul>
<li *ngFor="let event of group.value">
{{event.firstName}} {{event.lastName}}
</li>
</ul>
</li>
</ul>
这很完美!
但是我想做另一件事。
内部示例(应用组件): https://stackblitz.com/edit/angular-rc3njv
我有一个字符串数组:
email = ["bla@gmail.com", "ggg@gmail.com", "zzz@gmail.com","mmm@hotmail.com"]
,我想按子字符串将该数组分组。例如: @ gmail.com是一个群组,包含“ bla@gmail.com”,“ ggg@gmail.com”,“ zzz@gmail.com”; @hotmail是另一个组,包含“ mmm@hotmail.com”
有人知道如何自定义示例中实现的管道,以便按子字符串对字符串数组进行分组吗?
非常感谢!
答案 0 :(得分:1)
您可以尝试此方法,根据扩展名将其分组。
。还创建了 Stackblitz Demo 供您参考
您的样本数据:
const emails = ["bla@gmail.com", "ggg@gmail.com", "zzz@gmail.com","mmm@hotmail.com"];
方法1-采用
{ '@gmail.com': ['...', '...'] }
格式
// Fetches the extensions from the emails, used new Set to avoid duplicates
// Result: [ '@gmail.com', '@hotmail.com' ]
const extensions = Array.from(new Set(emails.map(email => email.match(/@.*/ig)[0])));
// Returns an index of the extension from extensions (list above) if the condition met where the email passed has a keyword of either from these two [ '@gmail.com', '@hotmail.com' ]
// Result: e.g bla@gmail.com -> 0 as '@gmail.com' is found on index 0 of extensions [ '@gmail.com', '@hotmail.com' ]
const getEmailExtensionIndex = email => extensions.findIndex(extension => email.includes(extension));
// Group them based on their extensions
const result = emails.reduce((acc, email) => {
// Get the extension of the specified email e.g bla@gmail.com -> @gmail.com
const extension = extensions[getEmailExtensionIndex(email)];
// If example @gmail.com key doesn't exist inside the object acc, specify an initial value
if (!acc[extension]) acc[extension] = [];
// Push the email to it's corresponding key inside the object
// If extension is equal to '@gmail.com' then { '@gmail.com': [ 'bla@gmail.com' ] } and so on
acc[extension].push(email);
return acc;
}, {});
结果:
{
'@gmail.com': [ 'bla@gmail.com', 'ggg@gmail.com', 'zzz@gmail.com' ],
'@hotmail.com': [ 'mmm@hotmail.com' ]
}
方法2-采用
[ { key: '' , values: [] } ]
格式
// result is from the Method #1 const result = emails.reduce(...)
const result2 = Object.keys(result).map(key => ({ key, values: result[key] }));
结果:
[
{ key: '@gmail.com', values: [ 'bla@gmail.com', 'ggg@gmail.com', 'zzz@gmail.com' ] },
{ key: '@hotmail.com', values: [ 'mmm@hotmail.com' ] }
]