Javascript 映射然后过滤唯一数组项
Javascript map then filter unique array items
我知道如何分别做这两件事,但我相信一定有办法将它们结合起来。
我有一组类别,我正在从一组对象中提取它们:
this.videoCategories = this.videos.map(v => v.category);
但是这个数组中当然有重复项。所以现在我做
this.uniqueVideoCategories = this.videoCategories.filter((item, index) => {
return this.videoCategories.indexOf(item) === index;
});
效果很好,我得到了一组没有重复的类别。但是我试图通过将它们串在一起来学习和干涸代码,但这不起作用 - 产生空数组
constructor(private videoService: VideoService) {
this.videos = videoService.getVideos();
this.videoCategories = this.videos
.map(v => v.category)
.filter((item, index) => {
return this.videoCategories.indexOf(item) === index;
});
console.log(this.videoCategories);
}
在 filter()
中,您正在检查对象数组中的索引。您可以使用 filter()
方法的第三个参数,它将是 map()
之后新创建的数组
constructor(private videoService: VideoService) {
this.videos = videoService.getVideos();
this.videoCategories = this.videos
.map(v => v.category)
.filter((item, index, arr) => {
return arr.indexOf(item) === index;
});
console.log(this.videoCategories);
}
您可以使用 Set
来删除重复项,而不是使用 filter()
和 indexOf()
。这将是时间复杂度 O(N)
constructor(private videoService: VideoService) {
this.videos = videoService.getVideos();
this.videoCategories = [...new Set(this.videos.map(v => v.category))]
console.log(this.videoCategories);
}
var videos = [
{ category: 'category1', title: 'Category 1'},
{ category: 'category1', title: 'Category 1'},
{ category: 'category1', title: 'Category 1'},
{ category: 'category2', title: 'Category 2'},
{ category: 'category2', title: 'Category 2'}
];
var categoryVideos =
videos
.map(v => v.category)
.filter((item, index, arr) => arr.indexOf(item) === index);
console.log(categoryVideos);
语法
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
参数
回调
函数是一个谓词,用于测试数组的每个元素。 Return true 保留元素,否则为 false。它接受三个参数:
- element: 数组中当前正在处理的元素。
- index:(可选)当前正在处理的元素在数组中的索引。
- 数组:(可选)调用了数组过滤器。
- thisArg:(可选)执行回调时用作 this 的值。
Return值
包含通过测试的元素的新数组。如果没有元素通过测试,将返回一个空数组。
有时解决方案是选择正确的数据结构。 ES6 引入了 Set
,它只包含唯一对象。
然后你就这样做:
this.videoCategories = new Set(this.videos.map(v => v.category))
唯一性将由浏览器实现处理,而不是弄乱您的代码库。
数组为空,因为当您过滤数组 return this.videoCategories.indexOf(item) === index;
时,字段 this.videoCategories
为空。
试一试:
this.videoCategories = this.videos
.map(v => v.category)
.filter((item, index, array) => {
return array.indexOf(item) === index;
});
我知道如何分别做这两件事,但我相信一定有办法将它们结合起来。
我有一组类别,我正在从一组对象中提取它们:
this.videoCategories = this.videos.map(v => v.category);
但是这个数组中当然有重复项。所以现在我做
this.uniqueVideoCategories = this.videoCategories.filter((item, index) => {
return this.videoCategories.indexOf(item) === index;
});
效果很好,我得到了一组没有重复的类别。但是我试图通过将它们串在一起来学习和干涸代码,但这不起作用 - 产生空数组
constructor(private videoService: VideoService) {
this.videos = videoService.getVideos();
this.videoCategories = this.videos
.map(v => v.category)
.filter((item, index) => {
return this.videoCategories.indexOf(item) === index;
});
console.log(this.videoCategories);
}
在 filter()
中,您正在检查对象数组中的索引。您可以使用 filter()
方法的第三个参数,它将是 map()
constructor(private videoService: VideoService) {
this.videos = videoService.getVideos();
this.videoCategories = this.videos
.map(v => v.category)
.filter((item, index, arr) => {
return arr.indexOf(item) === index;
});
console.log(this.videoCategories);
}
您可以使用 Set
来删除重复项,而不是使用 filter()
和 indexOf()
。这将是时间复杂度 O(N)
constructor(private videoService: VideoService) {
this.videos = videoService.getVideos();
this.videoCategories = [...new Set(this.videos.map(v => v.category))]
console.log(this.videoCategories);
}
var videos = [
{ category: 'category1', title: 'Category 1'},
{ category: 'category1', title: 'Category 1'},
{ category: 'category1', title: 'Category 1'},
{ category: 'category2', title: 'Category 2'},
{ category: 'category2', title: 'Category 2'}
];
var categoryVideos =
videos
.map(v => v.category)
.filter((item, index, arr) => arr.indexOf(item) === index);
console.log(categoryVideos);
语法
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
参数
回调
函数是一个谓词,用于测试数组的每个元素。 Return true 保留元素,否则为 false。它接受三个参数:
- element: 数组中当前正在处理的元素。
- index:(可选)当前正在处理的元素在数组中的索引。
- 数组:(可选)调用了数组过滤器。
- thisArg:(可选)执行回调时用作 this 的值。
Return值
包含通过测试的元素的新数组。如果没有元素通过测试,将返回一个空数组。
有时解决方案是选择正确的数据结构。 ES6 引入了 Set
,它只包含唯一对象。
然后你就这样做:
this.videoCategories = new Set(this.videos.map(v => v.category))
唯一性将由浏览器实现处理,而不是弄乱您的代码库。
数组为空,因为当您过滤数组 return this.videoCategories.indexOf(item) === index;
时,字段 this.videoCategories
为空。
试一试:
this.videoCategories = this.videos
.map(v => v.category)
.filter((item, index, array) => {
return array.indexOf(item) === index;
});