简体   繁体   English

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

[英]Filter array of objects with nested objects by multiple properties

I have an array of objects我有一个对象数组

[
{
    "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 "
    }
 }
]

and I'd like to search if the title and lyrics contain a search quote.我想搜索标题和歌词是否包含搜索引用。

I already know how to search by title only but I need to search by lyrics as well我已经知道如何只按标题搜索,但我也需要按歌词搜索

<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>

how can I search by both title and lyrics?如何同时按标题和歌词搜索?

Along with the song title you also need to check the same condition with the values of lyrics object.除了歌曲title ,您还需要检查与lyrics对象的值相同的条件。 You can get values of lyrics object by passing object to Object.values() .您可以通过将对象传递给Object.values()来获取lyrics对象的值。 And with Array.some() you can evaluate if there is any element satisfying condition.并且使用Array.some()您可以评估是否有任何元素满足条件。 As Array.some() returns a boolean it will make it easy to check.由于Array.some()返回一个布尔值,因此检查起来很容易。

fix would be.修复会。

 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));

Also, you need to check if the song title is null or undefined as a second object from songs missing title property.此外,您需要检查歌曲标题是否为 null 或未定义为缺少title属性的歌曲的第二个对象。 You can do that with Optional Chaining .您可以使用Optional Chaining来做到这一点。

Try to filter the lyrics object keys or values using the some method:尝试使用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>;

Maybe not the best answer but it's work.也许不是最好的答案,但它的工作。

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