Reputation: 4028
I am retrieving building geolocation data from a service, however in some cases some of the data will have missing properties.
Good data
[{
"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"
}]
Bad data
Missing Region or Building Name
{
"ModifiedOn": "2015-04-29 11:17:28.0",
"BuildingName": "Kings Landing",
"Latitude": "23.818051",
"Longitude": "-.154871",
}
After making my AJAX request I store the JSON response in an object called _regionAndBuildings
I want to clean out any bad data from it, so I tried the following code
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);
Output
Starting size : 209
Delete x 17
Ending size : 209
Why is this code not removing the bad elements in my JSON object?
Upvotes: 2
Views: 3224
Reputation: 272116
You can do it the other way round, filter
the array for good values:
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 !== ""
);
});
Upvotes: 1
Reputation: 1441
The first reason - you use &&
instead of ||
there:
_regionAndBuildings[i].BuildingName === undefined && _regionAndBuildings[i].Region === undefined
But you said:
Bad data
Missing Region or Building Name
The second reason - when you delete elements from array by delete
, you get a gap undefined
:
[<elem>, undefined, <elem>]
Elem was removed, but length will be the same.
You can remove undefined
by filter
later:
var newArray = yourArray.filter(function(item) { return item});
But best way is use slice
instead of delete
:
_regionAndBuildings.splice(i, 1);
Upvotes: 2
Reputation: 7117
In you given example
{
"ModifiedOn": "2015-04-29 11:17:28.0",
"BuildingName": "Kings Landing",
"Latitude": "23.818051",
"Longitude": "-.154871",
}
property BuildingName
or Region
is missing. It is more appropriate to usu hasOwnProperty
instead of _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);
}
}
Upvotes: 1
Reputation: 239473
There are two problems in your code.
As per the question
Missing Region or Building Name
You want to remove the elements of either Region or Building Name is missing. But the condition doesn't reflect that
if (_regionAndBuildings[i].BuildingName === undefined &&
_regionAndBuildings[i].Region === undefined)
Since you have used &&
operator, only when both the expressions are satisfied, the code inside if
condition will be executed. So, you need to change it with logical OR operator ||
, like this
if (_regionAndBuildings[i].BuildingName === undefined ||
_regionAndBuildings[i].Region === undefined)
When you use delete
operator on an array, the element in the array will be deleted, but the index will point to nothing. It means the length of the array will not change. Read more about it in this section
Instead, you can use Array.prototype.splice
, like this
_regionAndBuildings.splice(i, 1);
But, I prefer reconstructing the array without the elements you don't want, with Array.prototype.filter
, like this
var filteredBuildings = _regionAndBuildings.filter(function (currentObject) {
return currentObject.hasOwnProperty("BuildingName") &&
currentObject.hasOwnProperty("Region");
});
Now, the function passed will be run with all the items in the array and only if the function returns true
, the object will be included in the filtered result. So, if the object has both BuildingName
and Region
properties, only then it will be included in the result.
Note: I prefer using Object.hasOwnProperty
to check if the property exists in the object, rather than comparing the value against undefined
, because if the value of the property is actually undefined
, then we cannot differentiate between a non-existing property and a property with value undefined
.
Upvotes: 2
Reputation:
can you try :
if (typeof _regionAndBuildings[i].BuildingName === "undefined"
&& typeof _regionAndBuildings[i].Region === "undefined")
{
console.log("Deleting");
_regionAndBuildings.splice(i, 1);
}
Upvotes: 1