删除对象数组中的空对象键

Removing empty object keys in an array of objects

我正在尝试创建一个数组来总结另一个数组。我已经收到了一些非常好的想法 ,它们都在起作用,但它们都产生了另一个我似乎无法解决的障碍。

基于@kooiinc 的 ,我当前的代码如下所示:

var grants = [
    { id: "p_1", location: "loc_1", type: "A", funds: "5000" },
    { id: "p_2", location: "loc_2", type: "B", funds: "2000" },
    { id: "p_3", location: "loc_3", type: "C", funds:  "500" },
    { id: "p_2", location: "_ibid", type: "D", funds: "1000" },
    { id: "p_2", location: "_ibid", type: "E", funds: "3000" }
];
var projects = [];
grants.map(
function (v) {
    if (!(v.id in this)) {
        this[v.id] = v;
        projects.push(v);
    } else {
        var current = this[v.id];
        current.type = [v.type].concat(current.type);
        current.funds = [v.funds].concat(current.funds);
    }
}, {});

... 这给出了以下期望的结果(typefunds 连接到子数组中,其余的被推入不变):

[
    { "id": "p_1", "location": "loc_1", "type": "A", "funds": "5000" },
    { "id": "p_2", "location": "loc_2", "type": ["E","D","B"], "funds": ["3000","1000","2000"] },
    { "id": "p_3", "location": "loc_3", "type": "C", "funds": "500" }
]

但是,如果一些对象有一些未定义的键值,结果将在数组中有空值。例如像这样(查看 type 数组):

[
    { "id": "p_1", "location": "loc_1", "type": "A", "funds": "5000" },
    { "id": "p_2", "location": "loc_2", "type": ["E",null,null], "funds": ["3000","1000","2000"] },
    { "id": "p_3", "location": "loc_3", "type": "C", "funds": "500" }
]

(这里有一个fiddle同样的东西。)

之后我试图找到一种快速删除这些的方法(如 here or here),但由于某些原因 none 通常的方法(递归删除所有 undefined/null) 似乎工作,不管我把它们放在我的代码中的什么地方。他们不会给出错误,他们只是不会删除任何东西。

是否可能已经以某种方式排除了映射中未定义的键?

更新: 所以一些对象键不会有 任何 值,只有 [null,null,null] 而其他人会有一些但不是全部喜欢 ["E",null,null]。我们的想法是删除所有空项,如果什么都没有,则也删除对象键。

这样试试:

grants.map(
 function (v) {
    if (!(v.id in this)) {
        // => initialize if empty
        v.type = v.type || [];
        v.funds = v.funds || [];
        this[v.id] = v;
        projects.push(v);
    } else {
        var current = this[v.id];
        current.type = v.type ? [v.type].concat(current.type) : current.type;
        current.funds = v.funds ? [v.funds].concat(current.funds) : current.funds;
    }
 }, {});

现在结果中不会显示空值。

我认为您可以测试 typefunds 属性的出现,只有存在时才插入或更新元素。

a.type && a.funds && ...

var grants = [
        { id: "p_1", location: "loc_1", type: "A", funds: "5000" },
        { id: "p_2", location: "loc_2", funds: "2000" },
        { id: "p_3", location: "loc_3", type: "C", funds: "500" },
        { id: "p_2", location: "_ibid", funds: "1000" },
        { id: "p_2", location: "_ibid", type: "E", funds: "3000" }
    ],
    project = [];

grants.forEach(function (a) {
    a.type && a.funds && !project.some(function (b, i) {
        if (a.id === b.id) {
            project[i].type.push(a.type);
            project[i].funds.push(a.funds);
            return true;
        }
    }) && project.push({ id: a.id, location: a.location, type: [a.type], funds: [a.funds] });
});
document.write('<pre>' + JSON.stringify(project, 0, 4) + '</pre>');