英文:
Recoding for component API?
问题
I can help you with the translation. Here is the translation of the code you provided:
checkboxFilter: { genre: [], moods: [], tempo: [], theme: [] },
computed: {
filteredSongs: function (value, key) {
let fltrdSongs = this.songs;
if (
this.checkboxFilter.genre.length +
this.checkboxFilter.moods.length +
this.checkboxFilter.tempo.length +
this.checkboxFilter.theme.length > 0
) {
// checking if "genre" array has elements
if (this.checkboxFilter.genre.length > 0) {
fltrdSongs = this.songs.filter((song) => {
let length = this.checkboxFilter.genre.length;
while (length--) {
if ((song.genre).indexOf(this.checkboxFilter.genre[length]) != -1) {
return true;
}
}
});
}
if (this.checkboxFilter.moods.length > 0) {
fltrdSongs = fltrdSongs.filter((song) => {
let length = this.checkboxFilter.moods.length;
while (length--) {
if ((song.moods).indexOf(this.checkboxFilter.moods[length]) != -1) {
return true;
}
}
});
}
if (this.checkboxFilter.tempo.length > 0) {
fltrdSongs = fltrdSongs.filter((song) => {
let length = this.checkboxFilter.tempo.length;
while (length--) {
if ((song.tempo).indexOf(this.checkboxFilter.tempo[length]) != -1) {
return true;
}
}
});
}
if (this.checkboxFilter.theme.length > 0) {
fltrdSongs = fltrdSongs.filter((song) => {
let length = this.checkboxFilter.theme.length;
while (length--) {
if ((song.theme).indexOf(this.checkboxFilter.theme[length]) != -1) {
return true;
}
}
});
}
}
return fltrdSongs.filter((song) => {
return song.keywords.toLowerCase().match(this.search.toLowerCase()) ||
song.title.toLowerCase().match(this.search.toLowerCase()) ||
song.description.toLowerCase().match(this.search.toLowerCase());
});
},
},
And the second part:
const searchTerm = ref('');
const genreFilter = ref([]);
const moodsFilter = ref([]);
const tempoFilter = ref([]);
const themeFilter = ref([]);
const filteredTracks = computed(() => {
let filtered = useSong.tracks;
if (searchTerm.value) {
const term = searchTerm.value.toLowerCase();
filtered = filtered.filter((track) =>
track.description.toLowerCase().includes(term) ||
track.genre.toLowerCase().includes(term) ||
track.keywords.toLowerCase().includes(term) ||
track.moods.toLowerCase().includes(term)
);
}
if (genreFilter.value.length > 0) {
filtered = filtered.filter((track) => genreFilter.value.includes(track.genre));
}
if (moodsFilter.value.length > 0) {
filtered = filtered.filter((track) => moodsFilter.value.includes(track.moods));
}
if (tempoFilter.value.length > 0) {
filtered = filtered.filter((track) => tempoFilter.value.includes(track.tempo));
}
if (themeFilter.value.length > 0) {
filtered = filtered.filter((track) => themeFilter.value.includes(track.theme));
}
return filtered;
});
I hope this helps!
英文:
How would I write this for composition API using Vue 3?
checkboxFilter:{genre: [], moods: [], tempo: [], theme: []},
computed: {
filteredSongs: function(value, key){
let fltrdSongs = this.songs;
if(this.checkboxFilter.genre.length + this.checkboxFilter.moods.length + this.checkboxFilter.tempo.length + this.checkboxFilter.theme.length > 0) {
// checking if "genre" array has elements
if (this.checkboxFilter.genre.length > 0) {
fltrdSongs = this.songs.filter((song) => {
let length = this.checkboxFilter.genre.length;
while(length--){
if ((song.genre).indexOf(this.checkboxFilter.genre[length])!=-1) {
return true;
}
}
});
}
if(this.checkboxFilter.moods.length > 0) {
fltrdSongs = fltrdSongs.filter((song) => {
let length = this.checkboxFilter.moods.length;
while(length--){
if ((song.moods).indexOf(this.checkboxFilter.moods[length])!=-1) {
return true;
}
}
});
}
if(this.checkboxFilter.tempo.length > 0) {
fltrdSongs = fltrdSongs.filter((song) => {
let length = this.checkboxFilter.tempo.length;
while(length--){
if ((song.tempo).indexOf(this.checkboxFilter.tempo[length])!=-1) {
return true;
}
}
});
}
if(this.checkboxFilter.theme.length > 0) {
fltrdSongs = fltrdSongs.filter((song) => {
let length = this.checkboxFilter.theme.length;
while(length--){
if ((song.theme).indexOf(this.checkboxFilter.theme[length])!=-1) {
return true;
}
}
});
}
}
return fltrdSongs.filter((song) => {
return song.keywords.toLowerCase().match(this.search.toLowerCase()) ||
song.title.toLowerCase().match(this.search.toLowerCase()) ||
song.description.toLowerCase().match(this.search.toLowerCase())
});
},
I am attempting to change my website to the composition api format but I can't seem to get the checkboxes to filter as I want. I have already attempted to rewrite this but the problem I kept having was that each genre, mood, theme and tempo would only return the first string in the respective sections of the array of songs. What I want is to select a genre checkbox and have all tracks return that genre, even if it is number three in the genre list. At the moment it will only return the first one. Here is where I got to:
const searchTerm = ref('')
const genreFilter = ref([])
const moodsFilter = ref([])
const tempoFilter = ref([])
const themeFilter = ref([])
const filteredTracks = computed(() => {
let filtered = useSong.tracks;
if (searchTerm.value) {
const term = searchTerm.value.toLowerCase();
filtered = filtered.filter(track =>
track.description.toLowerCase().includes(term) ||
track.genre.toLowerCase().includes(term) ||
track.keywords.toLowerCase().includes(term) ||
track.moods.toLowerCase().includes(term)
);
}
if (genreFilter.value.length > 0) {
filtered = filtered.filter(track => genreFilter.value.includes(track.genre))
}
if (moodsFilter.value.length > 0) {
filtered = filtered.filter(track => moodsFilter.value.includes(track.moods))
}
if (tempoFilter.value.length > 0) {
filtered = filtered.filter(track => tempoFilter.value.includes(track.tempo))
}
if (themeFilter.value.length > 0) {
filtered = filtered.filter(track => themeFilter.value.includes(track.theme))
}
return filtered;
});
Thanks in advance.
Here is a link to the majority of the code:
SFC for the pages/components
答案1
得分: 1
筛选不成功的原因是因为 track.genre 是一个由多个流派组成的以逗号分隔的字符串。假设你选择的筛选条件是 "Rock" 和 "Pop",而你的歌曲的流派是 "Pop, Rock"。那么你的筛选条件会尝试执行以下操作:
["Rock", "Pop"].includes("Pop, Rock") // 找不到匹配
只有在 genreFilter 包含被测试的整个字符串时,筛选条件才会产生匹配,例如:
["Rock", "Pop", "Pop, Rock"].includes("Pop, Rock") // 找到 1 个匹配
处理这个问题的一种可能策略是使用 String.split() 将字符串 "Pop, Rock" 转换为一个字符串数组,然后测试该数组中的每个值是否与 genreFilter 数组中的每个值匹配。使用 Array.some() 可以这样做:
if (genreFilter.value.length > 0) {
const trackGenres = track.genre.split(', ');
filtered = filtered.filter(track =>
genreFilter.value.some(g => trackGenres.includes(g))
);
}
需要注意的一点是,每个具有多个流派的歌曲都必须以逗号空格 ", " 精确分隔。如果 JSON 缺少逗号之间的空格,或者流派名称中包含逗号,你将获得不良结果,需要重新考虑如何分割或考虑特殊情况。
英文:
The filter is not successful because track.genre is a comma separated string of multiple genres. Say your selected filters were "Rock" and "Pop" and your track has genre "Pop, Rock". Your filter is then trying to do:
["Rock", "Pop"].includes("Pop, Rock") // no match found
The filter would only produce a match here if the genreFilter included the entire string being tested, e.g.
["Rock", "Pop", "Pop, Rock"].includes("Pop, Rock") // 1 match found
One possible strategy to deal with this is to convert the string "Pop, Rock"
into an array of strings using String.split() then test every value in that array against every value in the genreFilter array. Using Array.some() you can do it like this:
if (genreFilter.value.length > 0) {
const trackGenres = track.genre.split(', ');
filtered = filtered.filter(track =>
genreFilter.value.some(g => trackGenres.includes(g))
);
}
One pitfall to watch out for is that every track with multiple genres needs to be separated exactly by comma space ", "
. If the JSON is missing a space between commas, or a genre has a comma as part of its name, you'll get a bad result and you'll need to rethink how you split and/or take into consideration special cases.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论