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

时间:2015-05-12 10:30:58

标签: javascript arrays json data-cleaning

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

良好的数据

[{
    "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);

输出

  

起始尺寸:209

     

删除x 17

     

结束大小:209

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

5 个答案:

答案 0 :(得分:2)

您的代码中存在两个问题。

  1. 根据问题

      

    缺少地区或建筑物名称

    您要删除任何Region元素或缺少Building Name。但条件并没有反映出

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

    由于您已使用&&运算符,因此只有满足两个表达式时,才会执行if条件中的代码。因此,您需要使用逻辑OR运算符||进行更改,如此

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

    中详细了解相关信息

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

    _regionAndBuildings.splice(i, 1);
    
  3. 但是,我更喜欢在没有你不想要的元素的情况下使用Array.prototype.filter来重建数组,就像这样

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

    现在,传递的函数将与数组中的所有项一起运行,并且只有当函数返回true时,对象才会包含在过滤结果中。因此,如果对象同时具有BuildingNameRegion属性,则只有它才会包含在结果中。

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

答案 1 :(得分:2)

第一个原因 - 您使用&&代替||

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

但你说:

  

错误数据

     

缺少区域建筑名称

第二个原因 - 当您从delete删除数组中的元素时,您会得到一个空白undefined

[<elem>, undefined, <elem>]

Elem被移除,但长度将是相同的。 您可以稍后undefined删除filter

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

但最好的方法是使用slice代替delete

_regionAndBuildings.splice(i, 1);

答案 2 :(得分:1)

你可以尝试一下:

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

答案 3 :(得分:1)

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

ngrok

答案 4 :(得分:1)

在你给出的例子中

{
    "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