theprogrammablemind_4wp
Version:
105 lines (100 loc) • 3.28 kB
JavaScript
function isObject(value) {
return typeof value === "object" && value !== null;
}
const merge = (value1, value2) => {
if (Array.isArray(value1) && Array.isArray(value2)) {
const merged = []
for (let i = 0; i < value1.length; ++i) {
merged.push(merge(value1[i], value2[i]))
}
return merged
}
if (isObject(value1) && isObject(value2)) {
return Object.assign({}, value1, value2)
}
}
const project = (object, filter) => {
if (!object) {
return
}
if (typeof object === 'string' || typeof object === 'number') {
return object
}
const projection = {}
const set = (property, value) => {
if (value === null || value === undefined) {
return
}
if (projection[property]) {
projection[property] = merge(value, projection[property])
} else {
projection[property] = value
}
}
if (Array.isArray(filter)) {
if (Array.isArray(object)) {
return object.map(element => project(element, filter))
} else {
for (let properties of filter) {
if (typeof properties === 'function') {
properties = properties(object)
}
if (typeof properties === 'object') {
if (properties.propertyLists) {
for (const propertyList in properties.propertyLists) {
if (object[propertyList]) {
for (const property of object[propertyList]) {
set(property, project(object[property], properties.propertyLists[propertyList]))
}
}
}
}
if (properties.valueLists) {
for (const listProperty in properties.valueLists) {
const old = object[listProperty]
if (Array.isArray(old)) {
set(listProperty, old.map((element) => project(element, properties.valueLists[listProperty])))
} else {
set(listProperty, project(old, properties.valueLists[listProperty]))
}
}
}
if (properties.properties) {
for (const property in properties.properties) {
const old = object[property]
set(property, project(old, properties.properties[property]))
}
}
if (properties.property) {
const property = properties.property
if (properties.isPropertyList) {
if (!Array.isArray(object[property])) {
continue
}
for (const propertyRef of object[property]) {
const old = object[propertyRef]
set(propertyRef, project(old, properties.filter))
}
} else {
const old = object[property]
set(property, project(old, properties.filter))
}
}
} else {
if (!Array.isArray(properties)) {
properties = [properties]
}
for (const property of properties) {
set(property, object[property])
}
}
}
}
} else if (typeof filter === 'object') {
for (const property of Object.keys(filter)) {
set(property, project(object[property], filter[property]))
}
}
return projection
}
module.exports = { project, merge }