UNPKG

sort-keys

Version:
74 lines (56 loc) 1.51 kB
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); }