У меня есть эта структура в моем угловом проекте:
export interface Campo {
id?: number;
nome?: string;
tabela?: Tabela;
campos?: Campo[];
}
export interface Tabela {
id?: number;
name?: string
arquivo?: Arquivo;
}
export interface Arquivo {
id?: number;
name?: string;
tabelas?: Tabela[];
}
т. е. в «Arquivo» много «Tabela», а в «Tabela» много «Campo». Я подписываюсь на службу, которая возвращает все «Campo», и я храню ее в переменной «campos». Эта служба возвращает более 200 «Campos», связанных с примерно 10 «Tabelas» и только 3 «Arquivos».
Я хочу вернуть все уникальные "Arquivo" (т.е. все 3 "Arquivo").
Когда я делаю:
let arquivos = this.campos
.map(campo => campo.tabela.arquivo.id)
.filter((value, index, self) => self.indexOf(value) === index);
Он возвращается
[1001, 1002, 1003]
Так что это идентификаторы всех трех "Arquivo", которые у меня есть. Но мне не нужны идентификаторы, мне нужны объекты "Arquivo". Когда я пытаюсь:
let arquivos = this.campos
.map(campo => campo.tabela.arquivo)
.filter((value, index, self) => self.indexOf(value) === index);
Он возвращает более 200 регистров, потому что у меня более 200 "Campos" и он не может знать, какой "Arquivos" уникален или нет.
Как я могу это сделать?
Нет, все в порядке. Спасибо за предложение.
Вы можете попробовать сопоставить уникальные идентификаторы arquivo с объектами arquivo, а затем получить значения
let arquivos = Object.values(this.campos
.map(campo => campo.tabela.arquivo)
.reduce((totals, arquivo) => {
if (!totals[arquivo.id]) {
totals[arquivo.id] = arquivo;
}
return totals;
}, {})
);
Спасибо Альберто. Но он возвращает мне массив только с данными 1 "Arquivo".
Извините, я перепутал аргументы сокращения. Попробуй еще раз @aseolin
Я бы рекомендовал создать объект, ключами которого являются идентификаторы arquivo, а значениями — объекты arquivo, а затем возвращать только значения этого объекта. Это позволяет легко избежать дубликатов без повторного поиска в массиве.