给定如下所示的对象,如何在层次结构中向上移动所有值,直到其父级不再被命名为_ignore?
在尝试将Excel CSV数据转换为嵌套的json对象时,我最终得到了如下内容:
// Old structure:
var obj = {
_root: {},
_top1: {
"_ignore": {
"_ignore": [
"I can no longer traverse down",
"so the list that contains this",
"text should be placed under the",
"_top1 node, which is the first",
"parent not named _ignore. It should",
"be the only child to '_top1'."
]
}
},
_top2: {}
}
不应该触及_root和_top2,但top1应该在最终结构中具有最低级别列表作为其值。我希望这个对象看起来像这样:
// Desired structure:
var obj = {
_root: {},
_top1: [
"I can no longer traverse down",
"so the list that contains this",
"text should be placed under the",
"_top1 node, which is the first",
"parent not named _ignore"
],
_top2: {}
}
我知道我已经处于递归领域,只是无法以适当的方式应用它。 非常感谢帮助/指导。
答案 0 :(得分:1)
也许这个功能可以帮到你:
const removeIgnore = (obj) => {
let newObj = Object.assign({}, obj);
const findStructure = (obj) => {
const keys = Object.keys(obj)
if (keys.length == 0) return obj
return (keys[0] === '_ignore') ? findStructure(obj[keys[0]]) : obj
}
for (k in newObj) newObj[k] = findStructure(newObj[k])
return newObj
}
它将迭代所有根密钥,并搜索不属于_ignore
密钥的最深层结构。将使用修改后的数据返回 new 对象。
演示:
/* 3 deeps _ignore */
var obj = {
_root: {},
_top1: {
"_ignore": {
"_ignore": {
"_ignore": [
"I can no longer traverse down",
"so the list that contains this",
"text should be placed under the",
"_top1 node, which is the first",
"parent not named _ignore. It should",
"be the only child to '_top1'."
]
}
}
},
_top2: {}
}
const newObj = removeIgnore(obj);
console.log(newObj);
/*
{ _root: {},
_top1:
[ 'I can no longer traverse down',
'so the list that contains this',
'text should be placed under the',
'_top1 node, which is the first',
'parent not named _ignore. It should',
'be the only child to \'_top1\'.' ],
_top2: {} }
*/
答案 1 :(得分:1)
您需要在树下进行深度优先搜索以替换忽略
var obj = {
_root: {},
_top1: {
"_ignore": {
"_ignore": [
"I can no longer traverse down",
"so the list that contains this",
"text should be placed under the",
"_top1 node, which is the first",
"parent not named _ignore. It should",
"be the only child to '_top1'."
]
}
},
_top2: {}
}
function hoistIgnore(item, parent, parent_key){
if(Array.isArray(item) || !(typeof item === "object")) {
parent[parent_key] = item;
return item
}
for(var key in item){
if(key === "_ignore"){
hoistIgnore(item[key], parent, parent_key);
} else {
hoistIgnore(item[key], item, key);
}
}
return item
}
console.log(hoistIgnore(obj))
答案 2 :(得分:1)
的确,你基本上只想要最深的 _ignore 的内容。由于您还要将所有祖先对象( obj 本身除外)转换为数组,因此可以安全地说可以销毁任何其他属性。换句话说,一个对象具有 _ignore 属性,或者是我们正在寻找的实际内容。
你可以用一句话说;给我 _ignore 的内容,如果有,并递归。
在伪代码中:
function findContents (level) {
if (i have an ignored level)
return findContents (ignored level)
else
return level
}
在Javascript代码中:
const findContents = obj => obj._ignore
? findContents(obj._ignore)
: obj;
并将其应用于您的结构:
obj._top1 = findContents(obj._top1);
玩得开心