繁体   English   中英

通过多个属性过滤具有嵌套对象的对象数组

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM