代码之家  ›  专栏  ›  技术社区  ›  tomen

按一个对象属性的长度对对象数组进行排序

  •  0
  • tomen  · 技术社区  · 7 年前

    [{
      id: 'card1',
      text: "Item1",
      votedBy: {
                 userId1: true,
                 userId2: true
               }
     }, 
     {
      id: 'card2',
      text: 'Item 1',
      votedBy: {
                 userId3: true
               }
     }, 
     {
      id: 'card3',
      text: 'Item 3'
     }, 
    {
      id: 'card4',
      text: "Item4",
      votedBy: {
                 userId5: true,
                 userId6: true,
                 userId7: true
               }
     }]
    

    我尝试使用Array.sort,如下所示

    array.sort((a,b) => Object.keys(b.votedBy).length - Object.keys(a.votedBy).length )
    

    而且,只有当每个对象都必须具有votedBy属性时,它才起作用。但是我的一些对象没有这个属性。

    结果应该是这样的

    [{
         {
          id: 'card4',
          text: "Item4",
          votedBy: {
                     userId5: true,
                     userId6: true,
                     userId7: true
                   }
         },
        {
          id: 'card1',
          text: "Item1",
          votedBy: {
                     userId1: true,
                     userId2: true
                   }
         }, 
         {
          id: 'card2',
          text: 'Item 1',
          votedBy: {
                     userId3: true
                   }
         }, 
         {
          id: 'card3',
          text: 'Item 3'
         }, 
    ]
    

    array.sort((a, b) => (
      Boolean(b.votedBy) - Boolean(a.votedBy)
      || Object.keys(b.votedBy).length - Object.keys(a.votedBy).length
    ));
    

    只有当我有一个没有sortedBy的对象时,它才起作用。如果我有多个没有sortedBy的对象,则有一个错误

    新的测试阵列应该是这样的

    [{
      id: 'card1',
      text: "Item1",
      votedBy: {
                 userId1: true,
                 userId2: true
               }
     }, 
     {
      id: 'card2',
      text: 'Item 1',
      votedBy: {
                 userId3: true
               }
     }, 
     {
      id: 'card3',
      text: 'Item 3'
     }, 
    {
      id: 'card4',
      text: "Item4",
      votedBy: {
                 userId5: true,
                 userId6: true,
                 userId7: true
               }
     },
     {
      id: 'card5',
      text: 'Item 5'
     } ]
    

    更新2

    我通过长而难看的代码使它工作。有没有人有更好更短的代码?

    array.sort((a, b) => {
      if (a.votedBy === undefined && b.votedBy === undefined)
      return Boolean(b.votedBy) - Boolean(a.votedBy)
      else if (a.votedBy === undefined) 
      return Object.keys(b.votedBy).length - Boolean(a.votedBy)
      else if (b.votedBy === undefined) 
      return Boolean(b.votedBy) - Object.keys(a.votedBy).length
      else return Object.keys(b.votedBy).length - Object.keys(a.votedBy).length
    });
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   CertainPerformance    7 年前

    第一类按是否存在差异排序 b.votedBy a.votedBy :

    array.sort((a, b) => (
      Boolean(b.votedBy) - Boolean(a.votedBy)
      || (
        a.votedBy &&
        Object.keys(b.votedBy).length - Object.keys(a.votedBy).length
      )
    ));
    

    const array = [{
        id: 'card1',
        text: "Item1",
        votedBy: {
          userId1: true,
          userId2: true
        }
      },
      {
        id: 'card2',
        text: 'Item 1',
        votedBy: {
          userId3: true
        }
      },
      {
        id: 'card3',
        text: 'Item 3'
      },
      {
        id: 'card4',
        text: "Item4",
        votedBy: {
          userId5: true,
          userId6: true,
          userId7: true
        }
      },
      { id: 'card5', text: 'Item 5' } 
    ];
    
    array.sort((a, b) => (
      Boolean(b.votedBy) - Boolean(a.votedBy)
      || (
        a.votedBy &&
        Object.keys(b.votedBy).length - Object.keys(a.votedBy).length
      )
    ));
    console.log(array);

    array.sort((a, b) => (
      Object.keys(b.votedBy || {}).length - Object.keys(a.votedBy || {}).length
    ));
    

    注意,如果有可能 votedBy 要获得真实的非对象值,您必须更加详细:

    (typeof b.votedBy === 'object') - (typeof a.votedBy === 'object')