过滤多个数组ngrx
filtering multiple arrays ngrx
我有一个包含多个数组的商店设置
我正在尝试通过文本字段一次搜索所有数组。
我可以通过在 keyup 上调用选择器函数来完成此操作,该函数过滤 4 个数组并推送到一个新数组。
我考虑过在过滤之前将所有数组合并为一个数组,但我想将结果分开,因为它们将按类别显示。
只是想看看我是否可以完全简化性能,以及是否有更简洁的方法来做到这一点,以防我需要对更大的数组做类似的事情。
我的 textField 函数:
this.renderer.listen(this.serachField.nativeElement, 'keyup', (event) => {
if (this.serachField.nativeElement.value.length < 3) { return; }
this.store.pipe(select(search(this.serachField.nativeElement.value)),take(1))
.subscribe(data => {
console.log(data);
});
})
选择器函数:
export const search = (searchString: string): any => {
return createSelector(
appState,
(state: AppState) => {
let arr: any = [];
let s = searchString.toUpperCase();
const comics = state.comics.results.filter((item: Comic) => {
let title = item.title.toUpperCase();
console.log(title);
return title.includes(s);
});
const music = state.music.items.filter((item: Album) => {
let title = item.name.toUpperCase();
console.log(title);
return title.includes(s);
});
const movies = state.movies.results.filter((item: Movie) => {
let title = item.title.toUpperCase();
console.log(title);
return title.includes(s);
});
const games = state.games.filter((item: Game) => {
let title = item.title.toUpperCase();
console.log(title);
return title.includes(s);
});
arr.push(comics, music, movies, games);
return arr;
}
);
};
编辑:@GustavMH 正确回答后,我不得不稍微更改代码,使其在数组命名方面更加动态,如下所示
export const search = (searchString: string): any => {
return createSelector(
appState,
(state: any) => {
let s = searchString.toUpperCase();
const keys = [{state: "comics", item: "title", array: 'results'},
{state: "music", item: "name", array: 'items'},
{state: "movies", item: "title", array: 'results'},
{state: "games", item: "title", array: ''}]
return keys.map((key) => {
let arr = key.array ? state[key.state][key.array] : state[key.state];
return arr.filter((item: any) => {
const title = item[key.item].toUpperCase();
console.log(item);
return title.includes(s);
})})
}
);
};
这应该可以用更少的代码实现选择器功能,使其更适应各种数据,如果需要,您可以在过滤器功能中指定更精确的类型。
export const search = (searchString: string): any => {
return createSelector(
appState,
(state: AppState) => {
let s = searchString.toUpperCase();
const keys = [{state: "comics", item: "title"},
{state: "music", item: "name"},
{state: "movies", item: "title"},
{state: "games", item: "title"}]
return keys.map(key => state[key.state].results.filter((item: any) => {
const title = item[key.item].toUpperCase();
console.log(title);
return title.includes(s);
}))
}
);
};
我有一个包含多个数组的商店设置
我正在尝试通过文本字段一次搜索所有数组。
我可以通过在 keyup 上调用选择器函数来完成此操作,该函数过滤 4 个数组并推送到一个新数组。
我考虑过在过滤之前将所有数组合并为一个数组,但我想将结果分开,因为它们将按类别显示。
只是想看看我是否可以完全简化性能,以及是否有更简洁的方法来做到这一点,以防我需要对更大的数组做类似的事情。
我的 textField 函数:
this.renderer.listen(this.serachField.nativeElement, 'keyup', (event) => {
if (this.serachField.nativeElement.value.length < 3) { return; }
this.store.pipe(select(search(this.serachField.nativeElement.value)),take(1))
.subscribe(data => {
console.log(data);
});
})
选择器函数:
export const search = (searchString: string): any => {
return createSelector(
appState,
(state: AppState) => {
let arr: any = [];
let s = searchString.toUpperCase();
const comics = state.comics.results.filter((item: Comic) => {
let title = item.title.toUpperCase();
console.log(title);
return title.includes(s);
});
const music = state.music.items.filter((item: Album) => {
let title = item.name.toUpperCase();
console.log(title);
return title.includes(s);
});
const movies = state.movies.results.filter((item: Movie) => {
let title = item.title.toUpperCase();
console.log(title);
return title.includes(s);
});
const games = state.games.filter((item: Game) => {
let title = item.title.toUpperCase();
console.log(title);
return title.includes(s);
});
arr.push(comics, music, movies, games);
return arr;
}
);
};
编辑:@GustavMH 正确回答后,我不得不稍微更改代码,使其在数组命名方面更加动态,如下所示
export const search = (searchString: string): any => {
return createSelector(
appState,
(state: any) => {
let s = searchString.toUpperCase();
const keys = [{state: "comics", item: "title", array: 'results'},
{state: "music", item: "name", array: 'items'},
{state: "movies", item: "title", array: 'results'},
{state: "games", item: "title", array: ''}]
return keys.map((key) => {
let arr = key.array ? state[key.state][key.array] : state[key.state];
return arr.filter((item: any) => {
const title = item[key.item].toUpperCase();
console.log(item);
return title.includes(s);
})})
}
);
};
这应该可以用更少的代码实现选择器功能,使其更适应各种数据,如果需要,您可以在过滤器功能中指定更精确的类型。
export const search = (searchString: string): any => {
return createSelector(
appState,
(state: AppState) => {
let s = searchString.toUpperCase();
const keys = [{state: "comics", item: "title"},
{state: "music", item: "name"},
{state: "movies", item: "title"},
{state: "games", item: "title"}]
return keys.map(key => state[key.state].results.filter((item: any) => {
const title = item[key.item].toUpperCase();
console.log(title);
return title.includes(s);
}))
}
);
};