【问题标题】:Loop through object and remove empties循环遍历对象并删除空
【发布时间】:2019-11-10 23:22:45
【问题描述】:

我正在使用 JSON API 规范 API v1.1。我正在让我的前端迎合这一点,但是,当我试图发回一段关系时,我遇到了一个小问题。

我本质上是在发送相同的对象并更改我需要的内容。

这是我如何做的一个例子:

{
    ...originalUser,
    attributes: {
        ...originalUser,
        lastName: 'Doe'
    }
}

这一切都很好,除非originalUser 的关系完全为空。我知道我可以做delete originalUser.relationships.relationship,这将从对象中删除属性,但这可能是任何关系,而且这种关系也可能具有听起来令人困惑的关系。

因此,我知道我需要递归地遍历对象并删除任何为空的对象,恐怕我不知道该怎么做,因为我需要调用一个方法,我有一个粗略的想法,它会像......

protected removeEmptyRelationships(obj) {
    return Object.keys(obj).filter((el) => {
        return el.hasOwnProperty('data');
    });
}

我可以发送的请求示例

{
    id: '1',
    type: 'users',
    attributes: {
        firstName: 'John',
        lastName: 'Doe'
    },
    relationships: {
        role: {
            data: {
                type: 'roles',
                id: '1'
            }
        },
        group: {
            data: {
                type: 'groups',
                id: '1',
                relationships: {
                    policy: {}
                }
            }
        },
        type: {}
    }
}

所以在上面的示例中,我希望删除 relationships.type 并且还需要删除 relationships.group.relationships.policy。显然,如前所述,这需要以编程方式删除,因为我不知道我需要删除什么对象。

我想看看的另一件事是,如果在删除空的关系后关系内部没有键,那么只需删除整个 relationships 对象。

【问题讨论】:

  • 如果您可以控制服务器端(听起来很像),那么在服务器上处理的效率会更高。只需发回您需要的 JSON,而不是您必须在客户端再次修改的 JSON。
  • 删除是指删除还是要获取没有属性的新对象?
  • @NinaScholz 要么,要么就可以,一个新对象也一样
  • 您如何在resource linkage object 上拥有relationships 键? (relationships.group.relationships) 根据 JSON:API 规范,不管它的价值如何,这都是无效的。如果您修复了该问题,则不必再递归检查对象,这将使删除空对象的任何解决方案(根据规范也无效)变得更加容易。您是否考虑过使用现有的 JSON:API 客户端不处理此类问题?
  • 嗨@jelhan,如果你看一下这里的例子(v1.1)你可以看到我们包括了cmets,这是一个关系,评论也有一个关系,它根据v1有效。 1. jsonapi.org/format/1.1/#document-compound-documents

标签: javascript object json-api


【解决方案1】:

您可以非常简单地将object 用作string 并使用正则表达式。
试试:

const obj = {
    id: '1',
    type: 'users',
    attributes: {
        firstName: 'John',
        lastName: 'Doe'
    },
    relationships: {
        role: {
            data: {
                type: 'roles',
                id: '1'
            }
        },
        group: {
            data: {
                type: 'groups',
                id: '1',
                relationships: {
                    policy: {}
                }
            }
        },
        type: {}
    }
}


const exp = /"\w*":{}/g;
const exp2 = /,}/g;
let strObj = JSON.stringify(obj);

while(exp.test(strObj)) {
    strObj = strObj.replace(exp,'');
}

strObj = strObj.replace(exp2, '}');
console.log(JSON.parse(strObj))

希望对您有所帮助。

【讨论】:

  • 好主意,避免循环
【解决方案2】:

您可以通过检查嵌套值并过滤掉此键/值对来删除不需要的属性。然后构建一个新对象。

function clean(object) {
    return Object.fromEntries(Object
        .entries(object)
        .map(([k, v]) => {
            if (v && typeof v === 'object') {
                v = clean(v);
                if (!Object.keys(v).length) return;
            }
            return [k, v];
        })
        .filter(Boolean)
    );
}

var data = { id: '1', type: 'users', attributes: { firstName: 'John', lastName: 'Doe' }, relationships: { role: { data: { type: 'roles', id: '1' } }, group: { data: { type: 'groups', id: '1', relationships: { policy: {} } } }, type: {} } },
    result = clean(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    猜你喜欢
    • 2017-07-16
    • 1970-01-01
    • 2012-03-16
    • 2020-06-09
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    相关资源
    最近更新 更多