从对象中清除错误的 JSON 数据?

Cleaning out bad JSON data from object?

我正在从服务中检索建筑地理位置数据,但在某些情况下,某些数据会缺少属性。

好数据

[{
    "ModifiedOn": "2015-04-29 11:17:28.0",
    "BuildingName": "Wintefell",
    "Latitude": "52.900619",
    "Longitude": "-1.434602",
    "Region": "The North",
}, {
    "ModifiedOn": "2015-04-29 11:17:28.0",
    "BuildingName": "Water Gardens",
    "Latitude": "51.818051",
    "Longitude": "-.354871",
    "Region": "Dorne"
}]

错误数据

缺少区域或建筑物名称

{
    "ModifiedOn": "2015-04-29 11:17:28.0",
    "BuildingName": "Kings Landing",
    "Latitude": "23.818051",
    "Longitude": "-.154871",
}

发出 AJAX 请求后,我将 JSON 响应存储在名为 _regionAndBuildings

的对象中

我想清除其中的任何不良数据,所以我尝试了以下代码

console.log("Starting size of building data : " + _regionAndBuildings.length);
//clean json by setting object to undefined
for (var i = 0; i < _regionAndBuildings.length; i++) {
    if (_regionAndBuildings[i].BuildingName === undefined && _regionAndBuildings[i].Region === undefined) {
        console.log("Deleting");
        delete _regionAndBuildings[i];
    }
}
console.log("Ending size of building data after cleaning : " + _regionAndBuildings.length);

输出

Starting size : 209

Delete x 17

Ending size : 209

为什么这段代码没有删除我的 JSON 对象中的坏元素?

您的代码中有两个问题。

  1. 根据问题

    Missing Region or Building Name

    您要删除缺少区域或建筑物名称的元素。但是条件并没有反映出

    if (_regionAndBuildings[i].BuildingName === undefined && 
        _regionAndBuildings[i].Region === undefined)
    

    由于你使用了&&运算符,只有当两个表达式都满足时,才会执行if条件内的代码。所以,你需要用逻辑或运算符||来改变它,像这样

    if (_regionAndBuildings[i].BuildingName === undefined ||
        _regionAndBuildings[i].Region === undefined)
    
  2. 当你在数组上使用delete运算符时,数组中的元素将被删除,但索引将不指向任何内容。这意味着数组的长度不会改变。在 this section

    中阅读更多相关信息

    相反,您可以使用 Array.prototype.splice,像这样

    _regionAndBuildings.splice(i, 1);
    

但是,我更喜欢在没有你不想要的元素的情况下重建数组,Array.prototype.filter,就像这样

var filteredBuildings = _regionAndBuildings.filter(function (currentObject) {
    return currentObject.hasOwnProperty("BuildingName") &&
        currentObject.hasOwnProperty("Region");
});

现在,传递的函数将 运行 包含数组中的所有项目,并且仅当函数 returns true 时,对象才会包含在过滤结果中。因此,如果对象同时具有 BuildingNameRegion 属性,那么它才会包含在结果中。


注意:我更喜欢使用Object.hasOwnProperty来检查对象中是否存在属性,而不是将值与undefined进行比较,因为如果 属性 的值实际上是 undefined,那么我们无法区分不存在的 属性 和值为 undefined 的 属性。

你能试试吗:

if (typeof _regionAndBuildings[i].BuildingName === "undefined" 
       && typeof _regionAndBuildings[i].Region === "undefined")
            {
                console.log("Deleting");
               _regionAndBuildings.splice(i, 1);
}

第一个原因 - 你在那里使用 && 而不是 ||:

_regionAndBuildings[i].BuildingName === undefined && _regionAndBuildings[i].Region === undefined

但是你说:

Bad data

Missing Region or Building Name

第二个原因 - 当您通过 delete 从数组中删除元素时,您会得到一个间隙 undefined:

[<elem>, undefined, <elem>]

Elem 已删除,但长度将保持不变。 您可以稍后通过 filter 删除 undefined

var newArray = yourArray.filter(function(item) { return item});

但最好的方法是使用 slice 而不是 delete:

_regionAndBuildings.splice(i, 1);

你可以反过来做,filter 好的值数组:

var goodRegionAndBuildings = _regionAndBuildings.filter(function(item) {
    // assumes not-empty strings are good
    // everything else is bad
    return (
        item.ModifiedOn !== "" &&
        item.BuildingName !== "" &&
        item.Latitude !== "" &&
        item.Longitude !== "" &&
        item.Region !== ""
    );
});

在你给出的例子中

{
    "ModifiedOn": "2015-04-29 11:17:28.0",
    "BuildingName": "Kings Landing",
    "Latitude": "23.818051",
    "Longitude": "-.154871",
}  

属性 BuildingNameRegion 缺失。使用 hasOwnProperty_regionAndBuildings[i].BuildingName === undefined

更合适
for (var i = 0; i < _regionAndBuildings.length; i++){
    if (!(_regionAndBuildings[i].hasOwnProperty('BuildingName')) && !(_regionAndBuildings[i].hasOwnProperty('Region'))) {
        console.log("Deleting");
        _regionAndBuildings.splice(i, 1);
     }
}  

DEMO