如何在javascript中完全删除空数组

How to completely remove an empty array in javascript?

本文关键字:删除 数组 javascript      更新时间:2024-03-21

我已经搜索了又搜索,找不到答案,所以如果我太愚蠢了,请接受我的道歉。

我正在node.js中构建一个使用JSON文件作为项目配置的应用程序。我使用"fs"模块读取JSON文件,然后将其解析为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

无论我走到哪里,人们都会惊讶地想从内存中删除一个未使用的数组,这正是我所想做的。也许有一种方法可以字符串化忽略这些空数组的对象?或者也许我做这件事的方式完全错了?

非常感谢您提供的任何建议。

编辑:我本应该更清楚地说,我不一定想删除数组中的所有元素,所以很遗憾,重新定义floors.runs=[]对我没有帮助。

我试过:

delete floors[floorID].runs[runID];

这将数组替换为null,null将被写入文件并破坏我对JSON的读取。

是否尝试重写每个对象的"runs"属性?如果您说floors[0].runs = [](或者floors[i].runs = [],如果您正在循环),那么这两个空数组将不再显示在字符串中。

编辑我的答案,以匹配OP编辑:

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

在我将你的对象从OP分配到一个变量中并在上面运行我的代码,然后字符串化结果后,我得到了一个返回:

{"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"}]]}]}

这就是你希望看到的吗?我用这把小提琴产生了那个结果。

如果您想从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;

Runs是对象的属性,您可以从该数组中删除项。在floors[0]之上的示例中。runs.splice(0,2),我认为应该删除这两个数组。

保持相同的引用

向下迭代使您可以安全地执行操作,每次时将阵列的长度减少1

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

制作新参考

使用.filter 可以创建一个没有您不想要的值的新阵列

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

要完全删除对象,必须从父对象中删除引用。要做到这一点,您可以创建一个新的Array,在其中只复制对非空数组的引用。

我已经创建了这个函数,它应该删除所有空数组。我还没有测试太多,但这应该会给你一个想法:

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);,并将在适当的位置更新Object。

演示:https://jsfiddle.net/zeo7dauh/