按对象的其中一个字段对对象进行排序以避免重复循环
Sort an object by one of its fields to avoid repeating a loop
我正在尝试对对象进行排序,这样它就不必执行 n 次相同的循环。
给定以下对象
movies = [
{
title: "The Lord of the Rings: The Fellowship of the Ring"
year: 2001
},
{
title: "The Lord of the Rings: The Two Towers"
year: 2002
},
{
title: "The Lord of the Rings: The Return of the King"
year: 2003
},
{
title: "A Beautiful Mind"
year: 2001
},
]
我希望电影按年份排序并出现在屏幕上:
Year 2003
- The Lord of the Rings: The Return of the King
Year 2002
- The Lord of the Rings: The Two Towers
Year 2001
- A Beautiful Mind
- The Lord of the Rings: The Fellowship of the Ring
要在 vue
中做到这一点,我可以做一些事情,比如定义一个对象 years = [2003, 2002, 2001]
然后
<div v-for="y in years">
{{ y }}
<div v-for="m in movies">
<div v-if="m.year == y">
{{ m.title }}
</div>
</div>
</div>
但是通过这种方式,我重复 movies
的 v-for
数组的长度 years
。
所以我考虑按以下方式组织 movies
对象:
moviesByYear = [
2003: [
{
title: "The Lord of the Rings: The Return of the King"
year: 2003
}
],
2002: [
{
title: "The Lord of the Rings: The Two Towers"
year: 2002
}
],
2001: [
{
title: "A Beautiful Mind"
year: 2001
},
{
title: "The Lord of the Rings: The Fellowship of the Ring"
year: 2001
}
]
]
那样我可以用
<div v-for="(movies, year) in moviesByYear" :key="year">
<div>{{ year }}</div>
<div v-for="m in movies">
{{ m.title }}
</div>
</div>
不幸的是,我无法构建 moviesByYear
数组,而且我不确定这是正确的方法,因为按键排序对象存在缺点。事实上,我需要按年份升序和降序对电影进行排序。
我该如何解决这个问题?有没有比运行v-for
n次更好的方法?
我可能有误会,但首先你需要创建一个包含 year => movie 关系的对象数组。您可以简单地通过反转数组来创建反向排序(升序)。这样你就可以使用一个简单的可迭代v-for,比如
<div v-for="year in movieList" >
<div>{{ year.year }}</div>
<div v-for="m in year.movies">
{{ m }}
</div>
</div>
let movies = [{
title: "The Lord of the Rings: The Fellowship of the Ring",
year: 2009
},
{
title: "The Lord of the Rings: The Two Towers",
year: 2002
},
{
title: "The Lord of the Rings: The Return of the King",
year: 2003
},
{
title: "A Beautiful Mind",
year: 2009
},
]
let movieList = movies.reduce((b, a) => {
let index = b.findIndex(f => f.year === a.year);
if (index < 0) b.push({
year: a.year,
movies: [a.title]
});
else b[index].movies.push(a.title);
return b;
}, []).sort((a, b) => b.year - a.year);
console.log(movieList)
console.log('reversed: ', movieList.reverse())
我正在尝试对对象进行排序,这样它就不必执行 n 次相同的循环。
给定以下对象
movies = [
{
title: "The Lord of the Rings: The Fellowship of the Ring"
year: 2001
},
{
title: "The Lord of the Rings: The Two Towers"
year: 2002
},
{
title: "The Lord of the Rings: The Return of the King"
year: 2003
},
{
title: "A Beautiful Mind"
year: 2001
},
]
我希望电影按年份排序并出现在屏幕上:
Year 2003
- The Lord of the Rings: The Return of the King
Year 2002
- The Lord of the Rings: The Two Towers
Year 2001
- A Beautiful Mind
- The Lord of the Rings: The Fellowship of the Ring
要在 vue
中做到这一点,我可以做一些事情,比如定义一个对象 years = [2003, 2002, 2001]
然后
<div v-for="y in years">
{{ y }}
<div v-for="m in movies">
<div v-if="m.year == y">
{{ m.title }}
</div>
</div>
</div>
但是通过这种方式,我重复 movies
的 v-for
数组的长度 years
。
所以我考虑按以下方式组织 movies
对象:
moviesByYear = [
2003: [
{
title: "The Lord of the Rings: The Return of the King"
year: 2003
}
],
2002: [
{
title: "The Lord of the Rings: The Two Towers"
year: 2002
}
],
2001: [
{
title: "A Beautiful Mind"
year: 2001
},
{
title: "The Lord of the Rings: The Fellowship of the Ring"
year: 2001
}
]
]
那样我可以用
<div v-for="(movies, year) in moviesByYear" :key="year">
<div>{{ year }}</div>
<div v-for="m in movies">
{{ m.title }}
</div>
</div>
不幸的是,我无法构建 moviesByYear
数组,而且我不确定这是正确的方法,因为按键排序对象存在缺点。事实上,我需要按年份升序和降序对电影进行排序。
我该如何解决这个问题?有没有比运行v-for
n次更好的方法?
我可能有误会,但首先你需要创建一个包含 year => movie 关系的对象数组。您可以简单地通过反转数组来创建反向排序(升序)。这样你就可以使用一个简单的可迭代v-for,比如
<div v-for="year in movieList" >
<div>{{ year.year }}</div>
<div v-for="m in year.movies">
{{ m }}
</div>
</div>
let movies = [{
title: "The Lord of the Rings: The Fellowship of the Ring",
year: 2009
},
{
title: "The Lord of the Rings: The Two Towers",
year: 2002
},
{
title: "The Lord of the Rings: The Return of the King",
year: 2003
},
{
title: "A Beautiful Mind",
year: 2009
},
]
let movieList = movies.reduce((b, a) => {
let index = b.findIndex(f => f.year === a.year);
if (index < 0) b.push({
year: a.year,
movies: [a.title]
});
else b[index].movies.push(a.title);
return b;
}, []).sort((a, b) => b.year - a.year);
console.log(movieList)
console.log('reversed: ', movieList.reverse())