diff --git a/package.json b/package.json index 9b3c964..94a9206 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tp/helpers", - "version": "2.10.3", + "version": "2.11.0", "description": "", "main": "closest.js", "scripts": { diff --git a/transform.js b/transform.js new file mode 100644 index 0000000..738da4c --- /dev/null +++ b/transform.js @@ -0,0 +1,49 @@ +import { reach } from './reach.js'; + +/** + * Transform an object or collection to a different form. + * + * @param {Object} source The object to transform. + * @param {Object} map Object that describes how to transform the source: { [path.in.transformed.object]: [path.in.source] }. + * @return {Object} A new object with the new structure. + */ +export const transform = (source, map) => { + const sep = '.'; + + if (Array.isArray(source)) { + const results = []; + for (let i = 0; i < source.length; ++i) { + results.push(transform(source[i], map)); + } + return results; + } + + const result = {}; + const keys = Object.keys(map); + + for (let i = 0, li = keys.length; i < li; ++i) { + const key = keys[i]; + const path = key.split(sep); + const srcPath = map[key]; + + if (typeof srcPath !== 'string') { + console.warn('Transformation path invalid. Skipping.'); + continue; + } + + let segment; + let res = result; + + while (path.length > 1) { + segment = path.shift(); + if (!res[segment]) { + res[segment] = {}; + } + res = res[segment]; + } + segment = path.shift(); + res[segment] = reach(srcPath, source); + } + + return result; +} \ No newline at end of file