Как записать данные в родительский параметр объекта
Столкнулся с проблемой с тем, что нужно обработать сложный формат данных и результат выполнения функции записать в родительский параметр.
К примеру
parse({
email: { __value__: 'mailingList[0].email' }
}, {mailingList: [{ email: '[email protected]' }]})
// на выходе должно получиться { email: '[email protected]' }
На данный момент у меня не получается записать в родителя (email). Вот как у меня выходит
{email: { __value__: '[email protected]' }}
И нужно реализовать пример со сложной структурой
parse({
user: {
email: {
__value__: 'mailingList[0].email',
},
password: {
__random__: {
minLength: {
__value__: 'minPasswordLength',
},
maxLength: {
__value__: 'maxPasswordLength',
},
},
},
},
}, // что необходимо обработать
{
mailingList: [{ email: '[email protected]' }],
minPasswordLength: 6,
maxPasswordLength: 24,
} // полезная нагрузка
)
Что должно получиться на выходе:
{email: '[email protected]', password: 'randomstring'}
__value__, __random__, и т.п. - это js функции, в которые можно передавать в качестве параметров: 1. объект, число, строку, массив , 2. это данные ( полезная нагрузка ).
К примеру value, принимает строку, путь к объекту полезной нагрузки (data).
__value__('mailingList[0].email',{mailingList: [{ email: '[email protected]' }]}) // => [email protected]
Мой код
const methods: Map<string, Function> = new Map<string, Function>()
methods.set('__value__', __value__)
function parse(obj: Input, data: object): Input {
if (_.isObject(obj)) {
_.mapKeys(obj, (val, key) => {
const fn = methods.get(key)
if (fn) {
obj[key] = fn(val, data)
}
})
}
return obj
}
function __value__(obj: Input, data: object): Input {
if (Array.isArray(obj) || typeof obj === 'string') {
return _.get(data, obj, obj)
}
return build(obj, data)
}
Ответы (2 шт):
Автор решения: qwabra
→ Ссылка
key должен быть __value__
см. TODO в коде
const log = (...q) => console.log('debug:', ...q)
const methods = new Map()
methods.set('__value__', __value__)
function __value__(obj, data) {
if (_.isArray(obj) || typeof obj === 'string') {
return _.get(data, obj, obj)
}
return build(obj, data)
}
function parse(obj, data) {
if (_.isObject(obj)) {
_.mapKeys(obj, (val, key) => {
// TODO: тут необхожимо пройтись по ещё одному уровню вложенности
// `key` должен быть `__value__`
log({ key })
const fn = methods.get(key)
if (fn) {
obj[key] = fn(val, data)
}
// решение
else if(_.isObject(obj[key])) {
obj[key] = parse(obj[key], data)
}
})
}
return obj
}
const res = parse(
{
email: { __value__: 'mailingList[0].email' }
},
{
mailingList: [{ email: '[email protected]' }]
}
)
log({ res })
<script src="http://unpkg.com/lodash"></script>
Автор решения: polRk
→ Ссылка
Вот мое решение ( Если кому будет интересно )
public compile(input?: Input): Input {
let obj: Input = input || { ...this.root }
if (obj != null && typeof obj === 'object') {
const keys = _.keys(obj)
if (keys.length === 1 && !Array.isArray(obj)) {
const key = keys[0]
const fn = this.fns.get(key)
if (fn) {
obj = this.compile(fn(obj[key]))
} else {
_.set(obj, key, this.compile(obj[key]))
}
} else {
for (const key of keys) {
_.set(obj, key, this.compile(_.get(obj, key)))
}
}
}
return obj
}