1

I have searched and searched and cannot find an answer to this, so please accept my apologies if I am being foolish.

I am building an application in node.js that uses JSON files as project configs. I am using the 'fs' module to read the JSON file, which I then parse into a Javascript object. I then amend details within the object before using JSON.stringify to write the data back to the file.

My problem is that I need to delete an array, not just empty it, in order to show the data correctly on my interface:

"floors": [
    {
        "floorName": "Grd Floor",
        "floorNotes": "",
        "floorPlan": "Buckley_Grd.jpg",
        "floorWidth": "57.392",
        "floorHeight": "20.776",
        "runs": [
            [],  *<----I cannot delete these*
            []   *<----only empty them*
            [
                {
                    "xCoOrd": "37.88235294117647",
                    "yCoOrd": "59.307359307359306",
                    "drawingType": "node"
                },
                {
                    "xCoOrd": "37.88235294117647",
                    "yCoOrd": "59.307359307359306",
                    "drawingType": "node"
                },
                {
                    "xCoOrd": "48.549019607843135",
                    "yCoOrd": "50",
                    "drawingType": "node"
                }
            ]   *<----I don't want to delete the elements in this array*
        ]
    }

I have tried:

.splice(0);
.filter(Boolean);
delete

Everywhere I have looked people seem surprised that one would want to delete an unused array from memory, which is what I beleive I am trying to do. Perhaps there is a way to stringify the object that ignores these empty arrays? Or perhaps I am doing this completely the wrong way?

Many thanks in advance for any advice offered.

EDIT: I should have made clearer that I don't necessarily want to delete all of the elemnets in the array so redeclaring floors.runs =[] unfortunately will not help me.

I have tried:

delete floors[floorID].runs[runID];

This replaces the array with null which gets written to the file and ruins my reading of the JSON.

4
  • 1
    How did you try delete? Commented Apr 9, 2016 at 13:16
  • have you tried to set "runs" to null ? Commented Apr 9, 2016 at 13:18
  • 1
    Define "delete an array". Clarify what exactly you tried, and why it didn't work for you. Commented Apr 9, 2016 at 13:21
  • To joke around, myarray="deleted".... What was an array is now something else :) Commented Apr 9, 2016 at 13:25

5 Answers 5

3

Did you try over-writing the 'runs' property of each object? If you said floors[0].runs = [] (or floors[i].runs = [], if you're looping through), then those two empty arrays would no longer show up in your stringify.

Editing my answer, to match the OP edits:

floors.forEach(function(floor){
   var newRuns = [];
   floor.runs.forEach(function(run){
       if (run.length > 0){
           newRuns.push(run);
       }
   })
   floor.runs = newRuns;
})

After I assign your object from the OP into a variable and run my code on it, then stringify the result, I get this as a return:

{"floors":[{"floorName":"Grd Floor","floorNotes":"","floorPlan":"Buckley_Grd.jpg","floorWidth":"57.392","floorHeight":"20.776","runs":[[{"xCoOrd":"37.88235294117647","yCoOrd":"59.307359307359306","drawingType":"node"},{"xCoOrd":"37.88235294117647","yCoOrd":"59.307359307359306","drawingType":"node"},{"xCoOrd":"48.549019607843135","yCoOrd":"50","drawingType":"node"}]]}]}

Is that what you're hoping to see? I used this fiddle to produce that result.

Sign up to request clarification or add additional context in comments.

4 Comments

Many thanks for your comment. From other comments it appears I have not been clear enough, so I will edit them. I want to delete individual elements within the array, but may need to keep others so to redeclare the array in this way would delete those would it not?
Yes, my original code would wipe out all references to anything that had been stored in runs. I updated my code to fit the edit you made to the OP. Let me know if it's not what you're looking for, I'll be happy to trying helping further.
This seems similar to Max' answer below and most appreciated as well! I have different parts of my code to add and delete entire individual elements from a run as well as entire runs and keep coming up against this issue whereby a null value creeps in. Since I am using the JSON to then plot a line onto a background, this stuffs everything up. Your code and Max's below both clear these values out. Many thanks!! (Not sure which one to mark as the answer though - possibly Max' as he answered first)
Yes, I would have totally understood if you accepted Max's first, we followed the same logic. I appreciate the accept, though -- and good luck with all in the future!
2

If you want remove ALL values from runs array you simply do this:

floors[i].runs = null

If you want remove only the empties

var filled = [];
obj.floors[i].runs.forEach(function(value, i, array) {
    if (value.length != 0) filled.push(value);
});

obj.floors[i].runs = filled;

1 Comment

Many thanks; I can see this being a good way of achieving the correct result. Jason's answer below seemed like a good one to me, but I have had problems with it before which I now cannot replicate for some reason, however this definitely works!!
0

Runs is a property of an object, you can remove items from that array. In your example above floors[0].runs.splice(0,2), should remove both of those arrays I think.

1 Comment

Many thanks. I have tried this and this seems the best solution, but genuinely I have this intermittent issue whereby it seems to replace the array with a null value when running on my local machine (Mac), but when i run on my Linux server it works perfectly! I am aware how crazy this sounds so if I have tried to upvote your response, but cannot as I am so new!! Thanks again!
0

Keeping the same reference

Iterating downwards lets you safely perform operations which decrease the length of an Array by 1 each time

var i, parentArray = obj['floors'][0]['runs'];
for (i = parentArray.length; i >= 0; --i) {
    if (parentArray[i].length === 0) parentArray.splice(i, 1);
}

Making a new reference

Creating a new array without the values you don't want can be achieved using .filter

obj['floors'][0]['runs'] = obj['floors'][0]['runs'].filter(function (x) {
    return x.length > 0;
});

Comments

0

To remove an object completely you have to remove the reference from the parent. To do this what you can do is create a new Array in which you copy only the references to the non-empty arrays.

I have created this function which should remove all empty arrays. I haven't tested it too much, but this should give you an idea:

function clearEmptyArrays(obj) {
   for(var key in obj) {

    var arr = obj[key];

    if(Array.isArray(arr)) {
      // Iterate through all elements and remove empty arrays
      var nonEmptyArr = [];
      for(var i = 0; i < arr.length; ++i) {
        // Recursive call if it's an object inside an array
        if(typeof arr[i] === 'object') clearEmptyArrays(arr);

        // Save all non-empty arrays or objects inside this one
        if((Array.isArray(arr[i]) && arr[i].length > 0) || !Array.isArray(arr[i])) {        
            nonEmptyArr.push(arr[i]);
         }
      }

      obj[key] = nonEmptyArr;
      return;
    }

    // Recursive call if it's an object
    if(typeof arr === 'object') {
        clearEmptyArrays(arr);
    }
  }
}

You can call it like this: clearEmptyArrays(myObj); and will update the Object in-place.

Demo: https://jsfiddle.net/zeo7dauh/

2 Comments

Many thanks. I can see this working on your jsfiddle, but for some reason in my code it does not.
Why it doesn't work? Do you get any errors? Probably there is something wrong with the recursivity.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.