在嵌套层次结构中向上移动JSON值,直到key不再命名为' _ignore'

时间:2017-02-05 04:00:35

标签: javascript json

给定如下所示的对象,如何在层次结构中向上移动所有值,直到其父级不再被命名为_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: {}
}

我知道我已经处于递归领域,只是无法以适当的方式应用它。 非常感谢帮助/指导。

3 个答案:

答案 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);

玩得开心