Reputation: 31
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.
Upvotes: 1
Views: 3903
Reputation: 181
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.
Upvotes: 3
Reputation: 28137
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/
Upvotes: 0
Reputation: 7080
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;
Upvotes: 2
Reputation: 66324
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);
}
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;
});
Upvotes: 0
Reputation: 118
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.
Upvotes: 0