Skip to content

Commit

Permalink
Support sorting of objects inside deep arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
coreyfarrell committed Apr 29, 2019
1 parent c5c02fe commit 584aa10
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 6 deletions.
42 changes: 36 additions & 6 deletions index.js
Expand Up @@ -2,14 +2,36 @@
const isPlainObj = require('is-plain-obj');

module.exports = (obj, opts = {}) => {
if (!isPlainObj(obj)) {
throw new TypeError('Expected a plain object');
}

const {deep} = opts;
const seenInput = [];
const seenOutput = [];

const deepSortArray = x => {
const seenIndex = seenInput.indexOf(x);

if (seenIndex !== -1) {
return seenOutput[seenIndex];
}

const ret = [];
seenInput.push(x);
seenOutput.push(ret);

ret.push(...x.map(y => {
if (Array.isArray(y)) {
return deepSortArray(y);
}

if (isPlainObj(y)) {
return sortKeys(y);
}

return y;
}));

return ret;
};

const sortKeys = x => {
const seenIndex = seenInput.indexOf(x);

Expand All @@ -27,7 +49,7 @@ module.exports = (obj, opts = {}) => {
const val = x[key];

if (deep && Array.isArray(val)) {
ret[key] = val.map(y => isPlainObj(y) ? sortKeys(y) : y);
ret[key] = deepSortArray(val);
continue;
}

Expand All @@ -37,5 +59,13 @@ module.exports = (obj, opts = {}) => {
return ret;
};

return sortKeys(obj);
if (isPlainObj(obj)) {
return sortKeys(obj);
}

if (Array.isArray(obj)) {
return deep ? deepSortArray(obj) : obj;
}

throw new TypeError('Expected a plain object or an array');
};
30 changes: 30 additions & 0 deletions test.js
Expand Up @@ -53,3 +53,33 @@ test('deep option', t => {
t.deepEqual(sortKeys({c: {c: 0, a: 0, b: 0}, a: 0, b: 0, z: [9, 8, 7, 6, 5]}, {deep: true}), {a: 0, b: 0, c: {a: 0, b: 0, c: 0}, z: [9, 8, 7, 6, 5]});
t.deepEqual(Object.keys(sortKeys({a: [{b: 0, a: 0}]}, {deep: true}).a[0]), ['a', 'b']);
});

test('deep arrays', t => {
const obj = {
b: 0,
a: [
{b: 0, a: 0},
[{b: 0, a: 0}]
]
};
const arr = [
[{b: 0, a: 0}]
];
obj.a.push(obj);
obj.a[1].push(obj.a[1]);

t.notThrows(() => {
sortKeys(arr);
sortKeys(arr, {deep: true});
sortKeys(obj, {deep: true});
});

const sorted = sortKeys(obj, {deep: true});
t.is(sorted.a[2], sorted);
t.is(sorted.a[1][1], sorted.a[1]);
t.deepEqual(Object.keys(sorted), ['a', 'b']);
t.deepEqual(Object.keys(sorted.a[0]), ['a', 'b']);
t.deepEqual(Object.keys(sorted.a[1][0]), ['a', 'b']);

t.deepEqual(Object.keys(sortKeys(arr, {deep: true})[0][0]), ['a', 'b']);
});

0 comments on commit 584aa10

Please sign in to comment.