简体   繁体   中英

Sort array of objects with keys nested at different levels

I'm using Gatsbyjs to query posts from 2 sources. Objects aren't uniform. I want posts sorted in descending order by date. The key used for sorting is nested at different levels depending on the object source. So I'm using Lodash to grab the deepest nested key and bring it a level higher. Then I sort the array.

https://jsbin.com/jetilahuxu/edit?js,console

In Javascript file:

const _ = require('lodash');

const posts=[
  {node: {excerpt: "Lorem1", fields: {id: 13}, frontmatter: {description: "lorem", date: "2020-11-25T20:17:10+0100", title: "Lorem1"}}},  
  {node: {excerpt: "Lorem3", fields: {id: 12}, frontmatter: {description: "lorem", date: "2020-11-22T20:17:10+0100", title: "Lorem3"}}},   
  {node: {id: 123, title: "Lorem4", created_at: "2020-11-20T20:17:10+0100", description: "Lorem ipsum"}}, 
  {node: {id: 124, title: "Lorem2", created_at: "2020-11-23T20:17:10+0100", description: "Lorem ipsum"}}
];

let array = []

posts.forEach(a => {

  if (_.get(a.node, 'created_at')) {
    array.push(a)
  }
  if (a.node.frontmatter) {
    a.node.created_at = _.get(a.node.frontmatter, 'date')
    array.push(a)
  }

})
array.sort((a, b) => new Date(b.node.created_at) - new Date(a.node.created_at));

console.log("SORTED ARRAY", array)

My question: Is there a better way to perform this sort? Tried aliasing in Graphql, other sorting functions, etc.

GraphQL Query in Gastby:

const pageQuery = graphql`
  query($skip: Int!, $limit: Int!) {
    site {
      siteMetadata {
        title
      }
    }
    sitePage {
      path
    }
    allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      limit: $limit
      skip: $skip
    ) {
      edges {
        node {
          excerpt(pruneLength: 300)
          fields {
            slug
          }
          frontmatter {
            date
            title
            readingtime
            description
            tags
            cover {
              childImageSharp {
                fluid(maxWidth: 170, maxHeight: 170, quality: 90) {
                  ...GatsbyImageSharpFluid_withWebp_tracedSVG
                }
              }
            }
          }
        }
      }
    }
    articleList: allInternalLinks(
      filter: {content: {ne: null }, alternative_id: {ne: null}}
      limit: $limit
      skip: $skip
    ) {
      edges {
          node {
              is_archived
              is_starred
              user_name
              user_email
              user_id
              is_public
              alternative_id
              title
              url
              content
              created_at
              updated_at
              published_at
              mimetype
              language
              reading_time
              domain_name
              preview_picture
              tags {
                label
              }
          }
      }
  }
  }
`

JS Bin: https://jsbin.com/jetilahuxu/edit?js,console

Thanks for all responses! Sincerely

Create a function that can get the date or the fallback (using lodash or vanilla), and apply it to each object when you sort. You can use Date.parse() to get the numeric value of a date and kip the object creation.

 const posts = [{"node":{"excerpt":"Lorem1","fields":{"id":13},"frontmatter":{"description":"lorem","date":"2020-11-25T20:17:10+0100","title":"Lorem1"}}},{"node":{"excerpt":"Lorem3","fields":{"id":12},"frontmatter":{"description":"lorem","date":"2020-11-22T20:17:10+0100","title":"Lorem3"}}},{"node":{"id":123,"title":"Lorem4","created_at":"2020-11-20T20:17:10+0100","description":"Lorem ipsum"}},{"node":{"id":124,"title":"Lorem2","created_at":"2020-11-23T20:17:10+0100","description":"Lorem ipsum"}}]; const getDate = ({ node }) => node.created_at?? node.frontmatter.date const result = [...posts].sort((a, b) => Date.parse(getDate(b)) - Date.parse(getDate(a)) ); console.log(result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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