|
|
@@ -0,0 +1,81 @@
|
|
|
+function isObject(value) {
|
|
|
+ if (value === null) return false;
|
|
|
+ if (typeof value !== 'object') return false;
|
|
|
+ if (Array.isArray(value)) return false;
|
|
|
+ if (Object.prototype.toString.call(value) === '[object Date]') return false;
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+export function clone(object) {
|
|
|
+ return Object.keys(object).reduce((values, name) => {
|
|
|
+ if (object.hasOwnProperty(name)) {
|
|
|
+ values[name] = object[name];
|
|
|
+ }
|
|
|
+ return values;
|
|
|
+ }, {});
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Flatten nested object into a single level object with 'foo.bar' property names
|
|
|
+ *
|
|
|
+ * The parameter object is left unchanged. All values in the returned object are scalar.
|
|
|
+ *
|
|
|
+ * cloneAndFlatten({ a: 1, b: { c: 2 }, d: { e: 3, f: { g: 4, h: 5 } }, i: { j: 6 } }, ['i'])
|
|
|
+ * // { a: 1, 'b.c': 2, 'd.e': 3, 'd.f.g': 4, 'd.f.h': 5, i: { j: 6 } } }
|
|
|
+ *
|
|
|
+ * @param {Object} object
|
|
|
+ * @param {String[]} excludedProperties
|
|
|
+ * @return {Object}
|
|
|
+ */
|
|
|
+export function cloneAndFlatten(object, excludedProperties = []) {
|
|
|
+ if (typeof object !== 'object') {
|
|
|
+ throw new Error('Expecting an object parameter');
|
|
|
+ }
|
|
|
+ return Object.keys(object).reduce((values, name) => {
|
|
|
+ if (!object.hasOwnProperty(name)) return values;
|
|
|
+ if (isObject(object[name])) {
|
|
|
+ if (excludedProperties.indexOf(name) === -1) {
|
|
|
+ let flatObject = cloneAndFlatten(object[name]);
|
|
|
+ Object.keys(flatObject).forEach(flatObjectKey => {
|
|
|
+ if (!flatObject.hasOwnProperty(flatObjectKey)) return;
|
|
|
+ values[name + '.' + flatObjectKey] = flatObject[flatObjectKey];
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ values[name] = clone(object[name]);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ values[name] = object[name];
|
|
|
+ }
|
|
|
+ return values;
|
|
|
+ }, {});
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * Clone flattened object into a nested object
|
|
|
+ *
|
|
|
+ * The parameter object is left unchanged.
|
|
|
+ *
|
|
|
+ * cloneAndNest({ a: 1, 'b.c': 2, 'd.e': 3, 'd.f.g': 4, 'd.f.h': 5 } )
|
|
|
+ * // { a: 1, b: { c: 2 }, d: { e: 3, f: { g: 4, h: 5 } } }
|
|
|
+ *
|
|
|
+ * @param {Object} object
|
|
|
+ * @return {Object}
|
|
|
+ */
|
|
|
+export function cloneAndNest(object) {
|
|
|
+ if (typeof object !== 'object') {
|
|
|
+ throw new Error('Expecting an object parameter');
|
|
|
+ }
|
|
|
+ return Object.keys(object).reduce((values, name) => {
|
|
|
+ if (!object.hasOwnProperty(name)) return values;
|
|
|
+ name.split('.').reduce((previous, current, index, list) => {
|
|
|
+ if (previous != null) {
|
|
|
+ if (typeof previous[current] === 'undefined') previous[current] = {};
|
|
|
+ if (index < (list.length - 1)) {
|
|
|
+ return previous[current];
|
|
|
+ };
|
|
|
+ previous[current] = object[name];
|
|
|
+ }
|
|
|
+ }, values)
|
|
|
+ return values;
|
|
|
+ }, {})
|
|
|
+}
|