How to filter out corrupt JSON data from an object?

There are times when retrieving building geolocation data from a service results in missing properties within the data.

Example of Good Data:

[{
    "ModifiedOn": "2015-04-29 11:17:28.0",
    "BuildingName": "Winterfell",
    "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"
}]

Example of Bad Data:

Missing Region or Building Name

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

Upon receiving the JSON response through an AJAX request, it is stored in an object named _regionAndBuildings.

The goal is to eliminate any bad data entries, so the following code was attempted:

console.log("Initial size of building data : " + _regionAndBuildings.length);
// Clean the JSON by setting objects 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("Final size of building data after cleanup : " + _regionAndBuildings.length);

Output:

Initial size : 209

Deleted x 17

Final size : 209

The issue arises when trying to remove the bad elements from the JSON object using the provided code. Why is this happening?

Answer №1

Your code has a couple of issues that need to be addressed:

  1. Firstly, regarding the condition in your code snippet:

    The issue lies in handling the scenario where either the Region or Building Name is missing.

    The current condition you have written does not accurately cater to this requirement:

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

    By using the logical AND operator, both conditions need to be met for the code inside the if statement to execute. In order to fix this, you should use the logical OR operator like so:

    if (_regionAndBuildings[i].BuildingName === undefined ||
        _regionAndBuildings[i].Region === undefined)
    
  2. The second problem pertains to utilizing the delete operator on an array:

    When delete is used on an array element, it removes the element itself but leaves behind an empty space at the index without changing the length of the array. For better management, consider using Array.prototype.splice instead:

    _regionAndBuildings.splice(i, 1);
    

A more efficient approach is reconstructing the array by filtering out unwanted elements using Array.prototype.filter method:

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

This function will iterate through all items in the array and only include objects that pass the specified criteria. If an object possesses both BuildingName and Region properties, it will make it into the filtered result.


Note: It's recommended to utilize Object.hasOwnProperty over comparing values against undefined when checking for property existence within an object. This is due to the distinction between non-existing properties and properties with an actual value of undefined.

Answer №2

One of the main issues is that the operator && is being used instead of ||:

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

This conflicts with the statement:

Bad data

Missing Region or Building Name

Additionally, removing elements from an array using delete leaves behind gaps of undefined:

[<elem>, undefined, <elem>]

While the length remains the same, you can eliminate these undefined values by using filter:

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

A better alternative is to use slice rather than delete:

_regionAndBuildings.splice(i, 1);

Answer №3

Could you attempt this:

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

Answer №4

Looking at the example you provided

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

The BuildingName or Region property is not present. It might be better to use hasOwnProperty instead of checking explicitly for

_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);
     }
}  

Check out the DEMO here

Answer №5

If you want to filter out the bad values from an array, you can do it in a different way by using the filter method:

var cleanRegionAndBuildings = _regionAndBuildings.filter(function(item) {
    // only keep items with non-empty strings
    return (
        item.ModifiedOn !== "" &&
        item.BuildingName !== "" &&
        item.Latitude !== "" &&
        item.Longitude !== "" &&
        item.Region !== ""
    );
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Interacting with Elements in three.js when the canvas is not in full screen mode version 74

Appreciate you taking the time to help me with my question. I'm having trouble finding a good example of how to use raycaster in three JS version r74. There have been many changes between versions r55 and r76, and forums seem to focus on examples fr ...

One way to achieve the same functionality as onclick in an Ajax call using

I have two JSPs. In the first JSP, I am making an ajax call and receiving data (Ajax body) from the second JSP. However, I am unsure of how to execute jQuery when an argument is present in the function. Everything works fine without an argument. In the ...

Trouble in Angular JS: Syntax glitches

Here is the factory that I am working with: (function() { angular.module('temp') .factory('Factory',Factory); employeeFactory.$inject = ['$http']; function employeeFactory($http) { var factory = {}; ...

Transforming BSON to JSON and delivering it as an API response using Haskell

I'm currently tackling my very first Haskell web application, and I've hit a roadblock when it comes to converting a BSON document into JSON and then sending it out as an API response. At the moment, I am utilizing the AesonBson package to transf ...

The implementation of various asynchronous Html.BeginForm scripts

I have created a webpage showcasing various products along with their details. The plan is for the details to be displayed when a button is clicked. I used a foreach loop to generate tables containing the products and a link to view more details. However, ...

Encountering an issue while attempting to send a POST response through Node Express, specifically an error related

Encountering an error after completing registration, specifically when attempting to respond to the POST request. (user is added to database successfully) express deprecated res.send(status, body): Use res.status(status).send(body) instead auth\regi ...

The second parameter within the ReactJS function is not defined

Exploring the world of ReactJS through a small project has been an enjoyable experience for me so far. I encountered a few challenges along the way, but this community has been helpful in resolving them. Currently, my focus is on modifying the links in th ...

Dealing with models in Vue.js is proving to be quite a challenge

Why isn't myGame showing as 超級馬力歐 initially and changing when the button is pressed? It just displays {{myGame}} instead. I'm not sure how to fix it, thank you! let myApp = new vue({ el:'myApp', data:{ myGame:&a ...

Tips for populating a textfield with data from a <select> dropdown using javascript

Is there a way to populate a textfield with data automatically based on information provided in the tab, utilizing JavaScript? Additionally, is it possible to prevent the filled data from being edited? The textfield should be able to dynamically fill data ...

A guide on creating extruded shapes using Three.JS

My intention was to create a 2x8 board using an extruded shape. However, despite including rounded corners in the shape, when I execute it, the result resembles more of a napalm bomb rather than a board. var beam = new THREE.Mesh( makeRectangle( inTOm(2), ...

The array is not receiving the objects as intended

I'm facing an issue with my event listener that is supposed to push new messages to an array, but it seems to only be pushing the strings. Here is the code snippet: async function consume() { try { let result = []; const connection = await a ...

Why did the Mongoose fail to cast to ObjectID for this value?

I'm facing an issue where I know what the problem is, but can't wrap my head around why it's happening. In my simple recipe app that utilizes express and mongoose, users input recipe information through a form which is then saved to the data ...

Checking for null properties in Typescript objectsorHow to verify if a

What is a simple way to determine if the properties of an object in TypeScript are nullable? For example export default interface UserDto{ ID?:int; USER_NAME?:string; FIRST_NAME?:string; LAST_NAME?:string; USER_ROLE?: ...

Struggling to style a nested table using CSS

Please take a look at this JSFiddle example for reference. I am currently working with tablesort and its associated CSS to achieve alternating row colors for the rows containing first and last names. Additionally, I want the rows within the sub-table disp ...

Performing math calculations on data inputted through a form in React Native

As a beginner in React Native, I am working on a simple app that consists of two screens: Calculator and Result. The Calculator screen has two input fields that only accept numeric values. Upon pressing the result button, the app should navigate to the Res ...

Is memory being corrupted during a single-line function call?

I am encountering a segmentation fault in my code that accesses an array of strings. The strange part is that I am losing memory across a single function call. Here is the snippet of my code: class A { void method1(){ std::cout << _my ...

Leveraging AngularJS $filter in conjunction with ng-disabled

I have a variable in my $scope that contains information about an election, including a list of voters with unique IDs: $scope.election = { voters: [ { _id: '123' }, { _id: '456' }, { _id: '789' } ] } Additio ...

techniques for extracting object values and transferring them into an array

I am trying to extract the filterPillvalue and store it in an array, where the output should look like this: mode = ['anyValue','Repsonding','Unresponsive'] My approach is as follows: this.items = [ { filterPillValue: & ...

Strange response received from $http GET request on Android device running Crosswalk

I am attempting to retrieve data in JSON format from an API using AngularJS. The process is successful on iOS and desktop browsers, but I'm encountering a strange response when trying it on my Android device. The request code looks like this: $http({ ...

There was an issue encountered while parsing the JSON Array

I have encountered an issue while trying to parse JSON data in my Android application : {"result":"success","source":"getPlayerNames","success":["Player1","Player2"]} My approach to parsing the data involves using a String called jsonData and implementin ...