1

Everyone, this is my Array Structure

let data = [
    {"name": "ragupathi", "siteID": 10},
    {"name": "abi","siteID": 13},
    {"name": "mahesh", "siteID": 12},
]

i want group data based on siteID so I am using groupBy siteID

let sample = _.groupBy(data,'siteID');

the current output is :

{
  "10": [
    {
      "name": "ragupathi",
      "siteID": 10
    }

  ],
  "12": [
    {
      "name": "mahesh",
      "siteID": 12
    }
  ],
  "13": [
    {
      "name": "abi",
      "siteID": 13
    }
  ]
}

But I am Expecting output name in ASC order

{
  "13": [
    {
      "name": "abi",
      "siteID": 13
    }
  ],
  "10": [
    {
      "name": "mahesh",
      "siteID": 12
    }
  ],
  "12": [
   {
      "name": "ragupathi",
      "siteID": 10
    }
   ],
}
  1. GroupBy SiteID
  2. Grouped Output based on properties of Object Name
Ragupathi
  • 391
  • 3
  • 17
  • [The order of object properties is not guaranteed](https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order), so you cannot expect `groupBy` to "order" the resulting properties in any way. – VLAZ May 10 '19 at 13:37
  • This is not possible. The output object has integer keys. In ES6, it will always be *traversed* in ascending order of those numbers irrespective of the order in which they were inserted. So, 10 -> 12 -> 13. You might want to [read this answer](https://stackoverflow.com/a/38218582/3082296) and [this blog post](http://2ality.com/2015/10/property-traversal-order-es6.html) – adiga May 10 '19 at 13:39
  • @adiga Yup... But if any possible to Change order give some idea I am new in javascript – Ragupathi May 10 '19 at 13:40
  • @Ragupathi if you need to order the items, you should use an array instead. Just map the final object by populating a new array where the objects are actually ordered by site ID instead. – briosheje May 10 '19 at 13:43
  • BTW, `groupBy` returns an array of all objects with same `siteID`. But, why does your output have only one object in each array? – adiga May 10 '19 at 13:55
  • @adiga based on siteID I will get external data – Ragupathi May 10 '19 at 14:02
  • @adiga sorry I posted wrong code this now i changed – Ragupathi May 10 '19 at 14:45
  • https://stackoverflow.com/q/1129216/125981 may help you – Mark Schultheiss May 11 '19 at 11:20

2 Answers2

0

The property order for objects in ES6 is:

  • The keys that are integer indices, in ascending numeric order.
  • Then, all other string keys, in the order in which they were added to the object.
  • Lastly, all symbol keys, in the order in which they were added to the object.

Reference

The output object has integer keys. No matter which order you insert the keys to the object, it will always be printed in the order: 10 -> 12 -> 13

You could use a Map as an output. Map objects hold key-value pairs and remember the original insertion order of the keys

Create an object with each unique siteID as key and an array with single object as value. Then sort the entries of the object based on the name of each object. Then create a Map from these sorted entries (Check the browser's console for the output. Stack snippets displays Map as an empty object)

let data = [
    {"name": "ragupathi", "siteID": 10},
    {"name": "abi", "siteID": 13},
    {"name": "abi","siteID": 13},
    {"name": "mahesh", "siteID": 12},
    {"name": "abi", "siteID": 13},
    {"name": "abi", "siteID": 13},
    {"name": "ragupathi", "siteID": 10}
]

const uniqueSiteGroups = {};
data.forEach(o => uniqueSiteGroups[o.siteID] = [o])

const sortedEntries = Object.entries(uniqueSiteGroups)
                        .sort((a, b) => a[1][0].name.localeCompare(b[1][0].name))

const map = new Map(sortedEntries)

console.log(map) // check the browser's console
adiga
  • 28,937
  • 7
  • 45
  • 66
0

Since order of the props is not guaranteed you have to utilize Map or other methods to get the sorting and the output you need.

You can use Array.sort, Array.forEach and Map like this:

let data = [{"name": "ragupathi", "siteID": 10},{"name": "abi", "siteID": 13},{"name": "abi","siteID": 13},{"name": "mahesh", "siteID": 12},{"name": "abi", "siteID": 13},{"name": "abi", "siteID": 13},{"name": "ragupathi", "siteID": 10}], 
map = new Map()

data
  .sort((a,b) => b.siteID - a.siteID)
  .forEach(x => map.set(x.siteID, [...(map.get(x.siteID) || []), x] || [x]))

console.log(map) // The map object output in your browser console
console.log(Array.from(map.values())) // The siteIds in array form    

Once you have them in the map object then you can access the groups easily by siteID like map.get(13) and you will get the array of the grouped items for the siteID of 13.

You can also always get the order in which you have stored the keys in the map via the Map.keys() method.

Akrion
  • 15,757
  • 1
  • 27
  • 43