deepsortobj
v0.1.3
Published
Deep-copy an object, with keys sorted. Supports circular references and custom sort order.
Downloads
129
Readme
deepsortobj
Deep-copy an object, with keys sorted. Supports circular references and custom sort order.
Beware! JS object key order rules
It's a mess. Detailed discussions on StackOverflow: here, here, here, here.
The gist of it: The spec gives some guarantees in some cases but they sound too complicated for me to memorize them. However, most JS engines (test yours) keep a tradition that results in:
- Keys that look like they could have been created by array operations (i.e. integers 0 ≤ n ≤ 4294967294 = 2^31-2 in default notation) always go first.
- Next up are all other string-y keys, in the order they were added.
- … and thus, the
numsLast
code shipped indeepsortobj
up to v0.1.1 was totally ineffective, besides being wrong. Starting from v0.1.2, thekeyPrefix
/keySuffix
hack might help in some cases.
API
sortObj(obj[, how])
The module exports this function.
Returns a sorted deep copy of obj
.
how
can be a function or an options object.
If it's a function, it's treated as the sort
option.
Supported options, all optional:
isArray
: How to decide whether to copy an object as an Array (with ascending indexes) or as a dictionary object, with keys sorted. Supported values:undefined
(default): UseArray.isArray
false
: Always sort.- any function: Should accept the object as its first argument and return the decision as boolean. All other arguments should be ignored because I haven't decided them yet.
dictKeys
: How to enumerate a dictionary's keys. Supported values:undefined
(default): UsesortObj.dictKeys
- any function: The function should accept the object as its first
argument and return either
false
(if the object is not a dictionary) or an Array of its keys.
sortKeys
: Determine which keys to copy from a dictionary, and in which order. Supported values:undefined
(default) ortrue
: UsesortObj.numsLast
false
: Don't modify the input array."fast"
: Just use the input array's.sort()
with no arguments.- any function: The function should accept an array of keys as its first argument and must return an array of keys.
keyPrefix
andkeySuffix
: On the result side (i.e. aftersortKeys
), wrap each key with these (default: empty) strings. You can use this to nullify the built-in priority of some number-like keys (see warning above).circular
: How to deal with circular references. Supported values:undefined
(default) or"congruent"
: Try to maintain the structure by putting a reference to the sorted version of the object. (Deprecated alias:"copy"
)"ign"
: Disable checking for CR. This should speed up stringification of non-circular objects, at the risk of running into infinite recursion ifobj
does contain a CR."err"
: Throw an exception when a CR is encountered. The exception thrown will be, or inherit from, an Error object, and it will have acircRef
property with a value other thanundefined
.- any function: Put the function's result instead of the CR. The function should ignore all arguments because I haven't decided them yet.
sortObj.numsLast(keys)
keys
must be an array of strings.
.numsLast
returns a copy of keys
, sorted in order
"texts first, integers last, both ascending",
where "integer" is defined as
intRgx = /^0$|^-?[1-9][0-9]*$/;
and a "text" is any string that's not an integer.
sortObj.dictKeys(x)
If x
is deemed some kind of dictionary,
return them as an Array, else return false
.
Currently, x
is considered a dictionary if it is an object but none of these:
- Array
- Buffer
- (Future versions might exclude more types, like typed arrays.)
Usage
From test/usage.demo.js:
var sortObj = require('deepsortobj'), pets = {
dog: { sounds: [ 'woof' ], colors: [ 'grey', 'white' ] },
cat: { colors: [ 'white', 'orange' ], sounds: [ 'meow', 'purr' ] },
ant: { colors: [ 'red', 'black' ], canRideOn: [ 'tree leaf' ] },
};
pets.ant.canRideOn.push(pets.dog);
pets.dog.favoritePassenger = pets.ant;
console.dir(sortObj(pets), { depth: 23 });
Output:
{ ant:
{ canRideOn:
[ 'tree leaf',
{ colors: [ 'grey', 'white' ],
favoritePassenger: [Circular],
sounds: [ 'woof' ] } ],
colors: [ 'red', 'black' ] },
cat: { colors: [ 'white', 'orange' ], sounds: [ 'meow', 'purr' ] },
dog:
{ colors: [ 'grey', 'white' ],
favoritePassenger:
{ canRideOn: [ 'tree leaf', [Circular] ],
colors: [ 'red', 'black' ] },
sounds: [ 'woof' ] } }
Known issues
- Needs more tests.
Related projects
- sortedjson and lots of other "sorted json" modules
- sorted-object
- sort-keys
- sort-object
License
ISC