Sort Array Of Objects By Number of Keys (JavaScript)

前端 未结 3 780
春和景丽
春和景丽 2021-01-16 19:36

Hi all I have an array of objects (20 of them) that I\'ve placed in this format to make columns in an Angular Project (note there are objects in objects). I want to sort the

相关标签:
3条回答
  • 2021-01-16 19:48

    Solution 1

    Using a custom comparator for Array.prototype.sort does what you need it to do

    let data = [{a:1,b:2,c:3}, {a:1}, {a:1,b:2,c:3,d:4}, {a:1,b:2}]
    
    data.sort((a,b) => Object.keys(a).length - Object.keys(b).length)
    
    console.log(data)

    Solution 2

    If your data is nested, the child data should be attached to a property of a known name

    let data = [
      {foo: 'W', bar: {a:1,b:2,c:3}},
      {foo: 'X', bar: {a:1}},
      {foo: 'Y', bar: {a:1,b:2,c:3,d:4}},
      {foo: 'Z', bar: {a:1,b:2}}
    ]
    
    let keyToSort = "bar";
    data.sort((a,b) => Object.keys(a[keyToSort]).length - Object.keys(b[keyToSort]).length)
    
    console.log(data)


    Traps and pitfalls

    On the other hand, if it is guaranteed to always have exactly one key (perhaps with an unknown/dynamic name), you could write

    Object.keys(a[Object.keys(a)[0]]).length
    

    This however is obviously very ugly and error prone (what if it does have more keys - or none at all). If you have control over the data structure, you should think about refactoring it, since an Object with only one key makes not much sense - you could as well just drop one nesting level.


    It's your future

    You should be in the habit of battling complexity — whenever it rears its stubborn head, grasp your staff and exert an equally stubborn force back upon it.

    The first solution above appears somewhat manageable, but the second one starts to get pretty thick. If you break your solution down into tiny reusable parts, you can keep complexity at bay with relative ease.

    const ascComparator = (a,b) => a < b ? -1 : a > b ? 1 : 0
    
    // use this if you want to sort data descending instead of ascending
    const descComparator = (a,b) => ascComparator(b,a)
    
    const prop = x => y => y[x]
    
    const len = prop('length')
    
    const comp = f => g => x => f (g (x))
    
    const keylen = comp (len) (Object.keys)
    
    let data = [
      {foo: 'W', bar: {a:1,b:2,c:3}},
      {foo: 'X', bar: {a:1}},
      {foo: 'Y', bar: {a:1,b:2,c:3,d:4}},
      {foo: 'Z', bar: {a:1,b:2}}
    ]
    
    // same as solution #2 but much more descriptive
    // "sort ascending using keylen of a.bar compared to keylen of b.bar"
    data.sort((a,b) => ascComparator(keylen(a.bar), keylen(b.bar)))
    
    console.log(data)

    Breaking complexity down is a way of investing in your future. Once you wrap a bit of complexity up in its own procedure, it will always be at your disposal at a later time. Smaller procedures are also easier to test.

    Each of the procedures above ascComparator, prop, len, comp, and keylen have immediately apparent intent. You can revisit these at any time and understand them with ease. And as a result of employing them, it makes your sort that much easier to read/write too.

    0 讨论(0)
  • 2021-01-16 20:03

    For your data structure you can use sort() like this.

    var arrayOfObjects = [
      {"least#OfKeysObject": {
        key1: 'value',
        }
      },
      {"secondMost#OfKeysObj": {
        key1: 'value',
        key2: 'value'
        }
      },
      {"most#OfKeysObj": {
        key1: 'value',
        key2: 'value',
        key3: 'value'
        }
      }
     ];
     
     var result = arrayOfObjects.sort(function(a, b) {
       return Object.keys(b[Object.keys(b)[0]]).length - Object.keys(a[Object.keys(a)[0]]).length;
     });
     
     console.log(result)

    0 讨论(0)
  • 2021-01-16 20:04

    Try

    arrayOfObjects.sort(function(a, b) {
        return Object.keys(a).length > Object.keys(b).length ? -1 : 1;
    });
    
    0 讨论(0)
提交回复
热议问题