如何完全删除JavaScript中的空数组?
我搜查了search,找不到答案,所以如果我是愚蠢的,请接受我的道歉。
我在使用JSON文件作为项目configuration的node.js中构build应用程序。 我正在使用'fs'模块来读取JSON文件,然后我parsing成一个Javascript对象。 然后在使用JSON.stringify将数据写回到文件之前,我修改对象中的细节。
我的问题是,我需要删除一个数组,而不是仅仅清空它,以便在我的界面上正确显示数据:
"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* ] }
我努力了:
.splice(0); .filter(Boolean); delete
我所看到的每个地方,人们似乎都很惊讶,希望从内存中删除一个未使用的数组,这正是我想要做的。 也许有一种方法来对忽略这些空数组的对象进行string化? 或者也许我完全是这样做的错误方式?
非常感谢您提供的任何build议。
编辑:我应该更清楚,我不一定要删除数组中的所有elemnets,所以重新声明floors.runs = []不幸的是不会帮助我。
我努力了:
delete floors[floorID].runs[runID];
这将replace数组写入该文件,并废除我的阅读JSON的数组。
如果你想从runs
数组中删除所有的值,你只需要这样做:
floors[i].runs = null
如果你只想删除空容器
var filled = []; obj.floors[i].runs.forEach(function(value, i, array) { if (value.length != 0) filled.push(value); }); obj.floors[i].runs = filled;
你是否试图重写每个对象的“运行”属性? 如果你说floors[0].runs = []
(或floors[i].runs = []
,如果你正在循环),那么这两个空的数组将不再显示在你的stringify中。
编辑我的答案,以匹配OP编辑:
floors.forEach(function(floor){ var newRuns = []; floor.runs.forEach(function(run){ if (run.length > 0){ newRuns.push(run); } }) floor.runs = newRuns; })
在我把你的对象从OP分配给一个variables并在其上运行我的代码之后,再对结果进行string化,我将其作为一个返回:
{"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"}]]}]}
那是你希望看到的吗? 我用这个小提琴来产生这个结果。
运行是对象的属性,您可以从该数组中删除项目。 在你的例子楼层[0] .runs.splice(0,2),应该删除我认为这两个数组。
保持相同的参考
向下迭代可以让您安全地执行每次减less1
的数组 长度的操作
var i, parentArray = obj['floors'][0]['runs']; for (i = parentArray.length; i >= 0; --i) { if (parentArray[i].length === 0) parentArray.splice(i, 1); }
做一个新的参考
创build一个没有你不想要的值的新数组可以使用.filter
来实现
obj['floors'][0]['runs'] = obj['floors'][0]['runs'].filter(function (x) { return x.length > 0; });
要完全删除对象,必须从父对象中删除引用。 要做到这一点,你可以做的是创build一个新的Array
,其中您只复制到非空数组的引用。
我创build了这个函数应该删除所有空数组。 我没有太多的testing,但这应该给你一个想法:
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); } } }
你可以这样调用它: clearEmptyArrays(myObj);
并将在原地更新对象。
演示: https : //jsfiddle.net/zeo7dauh/