【问题标题】:How to completely remove an empty array in javascript?如何在javascript中完全删除一个空数组?
【发布时间】:2016-04-09 13:13:41
【问题描述】:

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

我正在 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

我所看到的每一个地方,人们似乎都对想要从内存中删除一个未使用的数组感到惊讶,这就是我相信我正在尝试做的事情。也许有一种方法可以对忽略这些空数组的对象进行字符串化?或者也许我这样做完全错误?

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

编辑:我应该更清楚一点,我不一定要删除数组中的所有元素,所以重新声明 floor.runs =[] 不幸的是对我没有帮助。

我试过了:

delete floors[floorID].runs[runID];

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

【问题讨论】:

  • 你是如何尝试delete的?
  • 您是否尝试将“运行”设置为null
  • 定义“删除数组”。澄清您到底尝试了什么,以及为什么它对您不起作用。
  • 开个玩笑,myarray="deleted".... 原来的数组现在变成了别的东西 :)

标签: javascript json node.js


【解决方案1】:

您是否尝试过覆盖每个对象的“运行”属性?如果您说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"}]]}]}

这是您希望看到的吗?我用这个fiddle 来产生这个结果。

【讨论】:

  • 非常感谢您的评论。从其他 cmets 看来我还不够清楚,所以我将对其进行编辑。我想删除数组中的单个元素,但可能需要保留其他元素,因此以这种方式重新声明数组会删除那些不是吗?
  • 是的,我的原始代码会清除所有对运行中存储的任何内容的引用。我更新了我的代码以适应您对 OP 所做的编辑。如果这不是您想要的,请告诉我,我很乐意进一步提供帮助。
  • 这似乎与下面 Max 的回答相似,也最受赞赏!我有我的代码的不同部分来添加和删除整个运行以及整个运行中的整个单个元素,并不断遇到这个问题,即一个空值蔓延。因为我使用 JSON 然后在背景上绘制一条线,这把一切都搞砸了。您的代码和下面的 Max 都清除了这些值。非常感谢!! (虽然不确定将哪个标记为答案 - 可能是 Max',因为他首先回答)
  • 是的,如果你先接受 Max 的,我会完全理解的,我们遵循相同的逻辑。不过,我很感激你的接受——祝大家未来好运!
【解决方案2】:

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

【讨论】:

  • 非常感谢;我可以看到这是实现正确结果的好方法。下面杰森的回答对我来说似乎是一个很好的回答,但我之前遇到过问题,由于某种原因我现在无法复制,但这绝对有效!
【解决方案3】:

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

【讨论】:

  • 非常感谢。我已经尝试过了,这似乎是最好的解决方案,但实际上我遇到了这个间歇性问题,在我的本地机器(Mac)上运行时,它似乎用空值替换了数组,但是当我在我的 Linux 服务器上运行时,它工作得很好!我知道这听起来有多疯狂,所以如果我试图支持你的回应,但因为我太新了,所以不能!再次感谢!
【解决方案4】:

保持相同的引用

向下迭代可让您安全地执行将 Arraylength 每次减少 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;
});

【讨论】:

    【解决方案5】:

    要完全删除对象,您必须从父对象中删除引用。为此,您可以创建一个新的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); 并将就地更新对象。

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

    【讨论】:

    • 非常感谢。我可以看到这在你的 jsfiddle 上工作,但由于某种原因在我的代码中它没有。
    • 为什么它不起作用?你有任何错误吗?递归可能有问题。
    猜你喜欢
    • 2017-07-06
    • 2023-03-11
    • 2016-01-04
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多