sort-keys
Version:
Sort the keys of an object
74 lines (56 loc) • 1.51 kB
JavaScript
import isPlainObject from 'is-plain-obj';
export default function sortKeys(object, options = {}) {
if (!isPlainObject(object) && !Array.isArray(object)) {
throw new TypeError('Expected a plain object or array');
}
const {deep, compare} = options;
const seenInput = [];
const seenOutput = [];
const deepSortArray = array => {
const seenIndex = seenInput.indexOf(array);
if (seenIndex !== -1) {
return seenOutput[seenIndex];
}
const result = [];
seenInput.push(array);
seenOutput.push(result);
result.push(...array.map(item => {
if (Array.isArray(item)) {
return deepSortArray(item);
}
if (isPlainObject(item)) {
return _sortKeys(item);
}
return item;
}));
return result;
};
const _sortKeys = object => {
const seenIndex = seenInput.indexOf(object);
if (seenIndex !== -1) {
return seenOutput[seenIndex];
}
const result = {};
const keys = Object.keys(object).sort(compare);
seenInput.push(object);
seenOutput.push(result);
for (const key of keys) {
const value = object[key];
let newValue;
if (deep && Array.isArray(value)) {
newValue = deepSortArray(value);
} else {
newValue = deep && isPlainObject(value) ? _sortKeys(value) : value;
}
Object.defineProperty(result, key, {
...Object.getOwnPropertyDescriptor(object, key),
value: newValue
});
}
return result;
};
if (Array.isArray(object)) {
return deep ? deepSortArray(object) : object.slice();
}
return _sortKeys(object);
}