【问题标题】:Remove parent object of a JSON if it has certain property如果 JSON 具有特定属性,则删除它的父对象
【发布时间】:2016-05-03 00:40:17
【问题描述】:

我从 API 获取 JSON 结构,我想在前端进行更改。前端向 JSON 结构添加一个属性“isHidden”。当我发回修改后的 JSON 时,我不希望将具有“isHidden”的对象发送回 API,但我仍会将其保存在我自己的 mongodb 内部。

但是,这样做显然比我想象的要难一些。我做了这个功能,但我觉得很丑:

function removeHiddenObject(data,parent){
    for(var property in data){
        if(data.hasOwnProperty(property)){
            if(property == "isHidden" && data[property] === true){
                parent.splice(parent.indexOf(data), 1);
            }
            else {
                if(typeof data[property] === "object") {
                    removeHiddenObject(data[property], data);
                }
            }
        }
    }
    return data;
}

这是一种递归方法,但我觉得它复杂而奇怪。有没有办法简化我的任务?

如果你想帮忙,这里有一个 jsfiddle:https://jsfiddle.net/vn4vbne8/

【问题讨论】:

  • 将JSON视为字符串并替换isHidden然后将字符串转换回JSON会更容易吗!?

标签: javascript json recursion


【解决方案1】:

这是使用object-scan 的解决方案。花费一些时间来理解它,但它有助于解决一般数据处理方面的一些繁重工作。

// const objectScan = require('object-scan');

const data = {"user":{"name":"Bob"},"buildingBlockTree":[{"uid":"a875ed6cf4052448f9e0cc9ff092a76d4","_id":"56a7353f682e1cc615f4a6ae","columns":[{"uid":"a0061fdd2259146bb84e5362eeb775186","_id":"56a7353f682e1cc615f4a6b1","buildingBlocks":[{"user":{"name":"lajdi"},"buildingBlockTree":[{"uid":"a875ed6cf4052448f9e0cc9ff092a76d4","_id":"56a7353f682e1cc615f4a6ae","columns":[{"uid":"a0061fdd2259146bb84e5362eeb775186","_id":"56a7353f682e1cc615f4a6b1","buildingBlocks":[]},{"uid":"abbcf3328854840deb96bb6b101df2b39","_id":"56a7353f682e1cc615f4a6af","buildingBlocks":[{"uid":"a931cf745d4b847ba9cdc7f4b830413be","_id":"56a7353f682e1cc615f4a6b0","source":{"limit":1,"itemsListId":1,"offset":0}}]}],"template":{"name":"Xs12Sm12Md6Lg12DotXs12Sm12Md6Lg12"}}],"_id":"56a7353f682e1cc615f4a6ad","source":{"limit":1,"itemsListId":1,"offset":0},"template":{"numberOfColumns":1},"uid":"a5f6a2fd1c80f49c0b97e0c7994400588"}]},{"uid":"abbcf3328854840deb96bb6b101df2b39","_id":"56a7353f682e1cc615f4a6af","buildingBlocks":[{"_id":"56a7353f682e1cc615f4a6b0","source":{"limit":1,"itemsListId":1,"offset":0},"isHidden":true}]}]}],"_id":"56a7353f682e1cc615f4a6ad","source":{"limit":1,"itemsListId":1,"offset":0},"uid":"a5f6a2fd1c80f49c0b97e0c7994400588","metadata":{"title":"sss"},"title":"sss","url":"sss"};

const removeHiddenObjects = (input) => objectScan(['**[*].isHidden'], {
  rtn: 'count',
  filterFn: ({ value, gparent, gproperty }) => {
    if (value === true) {
      gparent.splice(gproperty, 1);
      return true;
    }
    return false;
  }
})(input);

console.log(removeHiddenObjects(data)); // counts removals
// => 1
console.log(data);
/* => {
  user: { name: 'Bob' },
  buildingBlockTree: [ {
    uid: 'a875ed6cf4052448f9e0cc9ff092a76d4',
    _id: '56a7353f682e1cc615f4a6ae',
    columns: [ {
      uid: 'a0061fdd2259146bb84e5362eeb775186',
      _id: '56a7353f682e1cc615f4a6b1',
      buildingBlocks: [ {
        user: { name: 'lajdi' },
        buildingBlockTree: [ {
          uid: 'a875ed6cf4052448f9e0cc9ff092a76d4', _id: '56a7353f682e1cc615f4a6ae', columns: [
            { uid: 'a0061fdd2259146bb84e5362eeb775186', _id: '56a7353f682e1cc615f4a6b1', buildingBlocks: [] },
            { uid: 'abbcf3328854840deb96bb6b101df2b39', _id: '56a7353f682e1cc615f4a6af', buildingBlocks: [
              { uid: 'a931cf745d4b847ba9cdc7f4b830413be', _id: '56a7353f682e1cc615f4a6b0', source: {
                limit: 1,
                itemsListId: 1,
                offset: 0
              } }
            ] }
          ],
          template: { name: 'Xs12Sm12Md6Lg12DotXs12Sm12Md6Lg12' }
        } ],
        _id: '56a7353f682e1cc615f4a6ad',
        source: { limit: 1, itemsListId: 1, offset: 0 },
        template: { numberOfColumns: 1 },
        uid: 'a5f6a2fd1c80f49c0b97e0c7994400588'
      } ]
    }, { uid: 'abbcf3328854840deb96bb6b101df2b39', _id: '56a7353f682e1cc615f4a6af', buildingBlocks: [] } ]
  } ],
  _id: '56a7353f682e1cc615f4a6ad',
  source: { limit: 1, itemsListId: 1, offset: 0 },
  uid: 'a5f6a2fd1c80f49c0b97e0c7994400588',
  metadata: { title: 'sss' },
  title: 'sss',
  url: 'sss'
}
*/
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@16.0.0"></script>

免责声明:我是object-scan的作者

【讨论】:

    【解决方案2】:

    使用此代码将其从 json 字符串中删除:

    myJson=s.replace(/,*\s*"[^"]"\s*\:\s*{(.*?)"isHidden"\:([^}]*)}/gm,"");
    

    注意正则表达式中的每个字符都很重要,因此请使用上面的代码。 它会删除所有具有一个对象的属性,该对象的属性之一是隐藏。

    【讨论】:

    • 我实际上想删除整个对象“isHidden”附加到。因此,如果它具有 isHidden 属性,则还应删除所有同级属性。这不这样做吗?还是这样?
    • 我编辑了答案,所以现在它就像你刚才说的那样工作。
    • 好的,这显然不符合我的公司政策,尽可能避免使用正则表达式。我会将此答案标记为正确,因为它有效。
    【解决方案3】:

    Javascript 实际上支持不可枚举的公共属性。我假设当您将数据发送回服务器时,您首先使用 JSON.stringify 对其进行字符串化,这只会将对象的公共 enumerable 属性字符串化。

    你可以像这样定义一个不可枚举的属性(更多关于这个here):

    Object.defineProperty(obj, 'isHidden', {
        enumerable: false,
        writable: true
    });
    

    其中obj 是您要添加属性的javascript 对象,isHidden 是您要添加的属性的名称。以这种方式完成后,新属性可以作为obj.isHidden 访问,但不会出现在JSON.stringify 输出或for 循环中。

    【讨论】:

    • 我希望删除 isHidden 属性所附加到的整个属性。这并不能解决这个问题,是吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    相关资源
    最近更新 更多