以下是具有某些深层属性的对象。
const InitialObj = {
Store: {propsFromStore: {}},
Market: {propsFromMarket: {}},
GoDown: {propsFromDown: {}},
fruits: {store_c: "Store", otherProp1: {store_e: "Store", otherSubProp1: {}}, otherProp2: {}},
vegetables: {market_d: "Market", otherProp1: {otherSubProp1: {godown_r: "GoDown", }}},
fancy:{store_t: "Store", market_d: "Market", otherProp1: {otherSubProp1: {godown_r: "GoDown", }}},
}
无论您在哪里看到“ Store”,“ Market”或“ GoDown”,都应将其替换为以下对象中的值-无论它们的深度如何。
// these values are not separate. there are part of the above initialObj.
//These values should replace Where ever you see "Store", "Market" or "GoDown", no matter how deep they are.
// The following values should be obtained from the above initialObj. & Not as a separate object.
Store: {propsFromStore: {}},
Market: {propsFromMarket: {}},
GoDown: {propsFromDown: {}},
这样最终结果将是: 预期结果
// this is what we get when the initialObj is transformed
// note that after removing all the occurences of "Store"/ "Market" / "GoDown"; these values will be removed so that final result looks like this. (with all placeholders replaced"
const finalExpectedResult = {
fruits: {store_c: {propsFromStore: {}, otherProps...}, otherProp1: {store_e: {propsFromStore: {}, otherProps...}, otherSubProp1: {}}, otherProp2: {}},
vegetables: {market_d: {propsFromMarket: {}, otherProps...}, otherProp1: {otherSubProp1: {godown_r: {propsFromDown: {}, otherProps...}, }}},
fancy:{store_t: {propsFromStore: {}, otherProps...}, market_d: {propsFromMarket: {}, otherProps...}, otherProp1: {otherSubProp1: {godown_r: {propsFromDown: {}, otherProps...}, }}},
}
请注意,这应该用相应的值替换“商店”,“市场”或“ GoDown”的所有深度出现
答案 0 :(得分:0)
显而易见的解决方案是简单地对所有对象属性进行递归迭代,但是对于这种简单情况,它可能不必要地复杂且耗时。假设我们要替换所有值实例,例如"Store"
之类的字符串,我们可以将对象转换为字符串并对其内容执行简单的replace函数,然后将其转换为对象。
const obj = {
Store: {propsFromStore: {}},
Market: {propsFromMarket: {}},
GoDown: {propsFromDown: {}},
fruits: {store_c: "Store", otherProp1: {store_e: "Store", otherSubProp1: {}}, otherProp2: {}},
vegetables: {market_d: "Market", otherProp1: {otherSubProp1: {godown_r: "GoDown", }}},
fancy:{store_t: "Store", market_d: "Market", otherProp1: {otherSubProp1: {godown_r: "GoDown" }}}
}
// please note the existence of ":" in front of the searched term which ensures the replaced value is actually a value not a key of the nested objects
const replaced = JSON.parse(JSON.stringify(obj)
.replace(/:"Store"/g, ": {\"propsFromStore\": {}}")
.replace(/:"Market"/g, ": {\"propsFromMarket\": {}}")
.replace(/:"GoDown"/g, ": {\"propsFromDown\": {}}"))
console.log(replaced)
当然,如果对象的属性更复杂/需要使用自己的自定义序列化方法,则此解决方案将无法工作。这种情况的一个示例:
const obj = { x: [10, undefined, null] }
console.log(JSON.stringify(obj)); // logs `{"x":[10,null,null]}` effectively losing distinction between undefined and null
const replaced = JSON.stringify(obj, (k, val) => typeof val === "undefined" ? "undefined" : val );
console.log(replaced) // with custom replacer can keep information that would otherwise be lost
const rereplaced = JSON.parse(replaced, (k, val) => val === "undefined" ? undefined : val)
console.log(rereplaced) // gets it's undefined value back
答案 1 :(得分:0)
您可以创建一个函数来检查键是“ Store”,“ Market”还是“ GoDown”之一,并将其替换为相应的值。 如果键的值是一个对象(typeof对象),则递归调用该函数并重复。
const obj = {
Store: {
propsFromStore: {}
},
Market: {
propsFromMarket: {}
},
GoDown: {
propsFromDown: {}
}
}
const whiteList = ["Store", "Market", "GoDown"]
const replacer = object => Object.fromEntries(Object
.entries(object)
.map(([key, value]) =>
[key, value && typeof value === "object" ? replacer(value) : whiteList.includes(value) ? obj[value] : value ]
)
)
var initialObj = {
fruits: {store_c: "Store", otherProp1: {store_e: "Store", otherSubProp1: {}}, otherProp2: {}},
vegetables: {market_d: "Market", otherProp1: {otherSubProp1: {godown_r: "GoDown", }}},
fancy:{store_t: "Store", market_d: "Market", otherProp1: {otherSubProp1: {godown_r: "GoDown", }}},
}
const finalObj = replacer(initialObj)
console.log(finalObj) // desired output
我希望这会有所帮助。
答案 2 :(得分:0)
您可以使用第一个函数来查找哪些道具应作为参考(商店,市场,GoDown),并通过辅助功能对其他道具使用递归:
const InitialObj = {
Store: {propsFromStore: {}},
Market: {propsFromMarket: {}},
GoDown: {propsFromDown: {}},
fruits: {store_c: "Store", otherProp1: {store_e: "Store", otherSubProp1: {}}, otherProp2: {}},
vegetables: {market_d: "Market", otherProp1: {otherSubProp1: {godown_r: "GoDown", }}},
fancy:{store_t: "Store", market_d: "Market", otherProp1: {otherSubProp1: {godown_r: "GoDown", }}},
};
function hydrateObj(obj, keys) {
const refs = keys.reduce((o, k) => ({...o, [k]: obj[k]}), {});
return Object.entries(obj).reduce((res, [k, v]) => {
if(!keys.includes(k)) {
res[k] = hydrateObjAux(v, keys, refs);
}
return res;
}, {});
}
function hydrateObjAux(obj, keys, refs) {
return Object.entries(obj).reduce((res, [k, v]) => {
if(keys.includes(v)) {
res[k] = refs[v];
} else {
res[k] = hydrateObjAux(v, keys, refs);
}
return res;
}, {});
}
const res = hydrateObj(InitialObj, ['Store', 'Market', 'GoDown']);
document.body.innerHTML = '<pre>' + JSON.stringify(res, 0, 4) + '</pre>';
答案 3 :(得分:0)
根据您的评论,您用大写的首字母将替换对象与InitialObj分开。
any
。如果使用ts,最好定义和设置正确的类型。
const InitialObj: any = {
Store: {propsFromStore: {}},
Market: {propsFromMarket: {}},
GoDown: {propsFromDown: {}},
fruits: {store_c: "Store", otherProp1: {store_e: "Store", otherSubProp1: {}}, otherProp2: {}},
vegetables: {market_d: "Market", otherProp1: {otherSubProp1: {godown_r: "GoDown", }}},
fancy:{store_t: "Store", market_d: "Market", otherProp1: {otherSubProp1: {godown_r: "GoDown", }}},
}
const replacementDict: any ={}
// take Store, Market, GoDown from InitialObj to replacementDict
Object.keys(InitialObj).forEach(key =>{
// Check if the first letter is capitalised or not
if(key[0].match(/^[A-Z]$/)){
replacementDict[key] = InitialObj[key]
delete InitialObj[key]
}
})
function converter(obj: any){
if(typeof obj !== "object") return
Object.entries(obj).forEach(([key, value]: [any, any]) => {
if(replacementDict[value]){
obj[key] = replacementDict[value]
}
if(typeof obj[key] === "object"){
converter(obj[key])
}
})
}
converter(InitialObj)
console.log(InitialObj)