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

时间:2019-01-23 00:51:54

标签: javascript arrays

我有一个对象数组。并且在每个纸牌对象中都有一个属性名称 votedBy ,该属性存储进行投票的人员的userId。我想按属性polldBy的长度对数组进行排序。注意:某些对象不具有投票属性。

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

仅当我有1个没有sortedBy的对象时,它才有效。如果我有1个以上没有sortedBy的对象,则会出现错误

未捕获的TypeError:无法将未定义或null转换为对象

新的测试数组应类似于

[{
  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 个答案:

答案 0 :(得分:2)

首先根据b.votedBya.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')