File size: 1,511 Bytes
bc20498 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
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);
}
|