[英]Filter array of objects with nested objects by multiple properties
我有一个对象数组
[
{
"createdAt": {
"seconds": 1654000036,
"nanoseconds": 204000000
},
"lyrics": {
"liryc-1-b": "Some example lyrics verse 1",
"liryc-1-a": "Some example lyrics verse 2"
},
"category": "maculele",
"title": "asdasd"
},
{
"category": "corridos",
"createdAt": {
"seconds": 1653936021,
"nanoseconds": 438000000
},
"lyrics": {
"liryc-1-b": "lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor ",
"liryc-1-a": "lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor "
}
}
]
我想搜索标题和歌词是否包含搜索引用。
我已经知道如何只按标题搜索,但我也需要按歌词搜索
<SongbookContainer>
{query === ''
? songs.map((song, i) => <SongPreview key={i} song={song} />)
: songs
.filter(song => song.title.toLowerCase().includes(query.toLowerCase()))
.map((filteredSong, i) => <SongPreview key={i} song={filteredSong} />)}
</SongbookContainer>
如何同时按标题和歌词搜索?
除了歌曲title
,您还需要检查与lyrics
对象的值相同的条件。 您可以通过将对象传递给Object.values()
来获取lyrics
对象的值。 并且使用Array.some()
您可以评估是否有任何元素满足条件。 由于Array.some()
返回一个布尔值,因此检查起来很容易。
修复会。
const songs = [ { "createdAt": { "seconds": 1654000036, "nanoseconds": 204000000 }, "lyrics": { "liryc-1-b": "Some example lyrics verse 1", "liryc-1-a": "Some example lyrics verse 2" }, "category": "maculele", "title": "asdasd" }, { "category": "corridos", "createdAt": { "seconds": 1653936021, "nanoseconds": 438000000 }, "lyrics": { "liryc-1-b": "lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor ", "liryc-1-a": "lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor lorem ipsum dolor " } } ] const query = 'dolor'; songs.filter(song => song.title?.toLowerCase().includes(query.toLowerCase()) || Object.values(song.lyrics)?.some(l => l.toLowerCase().includes(query.toLowerCase()))).map(r => console.log(r));
此外,您需要检查歌曲标题是否为 null 或未定义为缺少title
属性的歌曲的第二个对象。 您可以使用Optional Chaining来做到这一点。
尝试使用some
方法过滤lyrics
对象键或值:
<SongbookContainer>
{query === ''
? songs.map((song, i) => <SongPreview key={i} song={song} />)
: songs
.filter((song) => {
return song.title.toLowerCase().includes(query.toLowerCase()) &&
// If you need to filter by key
Object.keys(song.lyrics).some(lyricKey => lyricKey.toLowerCase().includes(query.toLowerCase()))
// Or, If you need to filter by value
Object.values(song.lyrics).some(lyricValue => lyricValue.toLowerCase().includes(query.toLowerCase()))
})
.map((filteredSong, i) => <SongPreview key={i} song={filteredSong} />)}
</SongbookContainer>;
也许不是最好的答案,但它的工作。
const query = "title";
/**
* tools to parse data any data to string and find correspond word.
*/
function wordExist(data, word) {
if (!data || !word) {
return false;
}
const parse = JSON.stringify(data);
return parse.includes(word);
}
// use like this in your current filter
array.filter(
(song) => wordExist(song.title, query) || wordExist(song?.lyrics, query)
)
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.