从对象数组中删除空条目

时间:2020-03-03 22:17:51

标签: javascript typescript

我在(组件)下面具有以下对象数组,并且我想删除所有空条目。我该怎么做呢?我正在尝试以下操作:

  static deleteNullComponents(components) {
    return components.filter(function (el) {
      return el['components'] != null;
    });
  }

但是出现错误:TypeError: components.filter is not a function。我该如何解决?

[
  {
    "components": [
      null,
      {
        "componentId": "navbar-zJNm0HaP",
        "componentIndex": 1,
        "componentName": "app-builder-navbar",
      },
      null,
      null,
      null,
      {
        "componentId": "features-MJU8gcYR",
        "componentIndex": 5,
        "componentName": "app-builder-features",
      },
      null,
      {
        "componentId": "features-2hsUdwaT",
        "componentIndex": 7,
        "componentName": "app-builder-features",
      },
      null,
      {
        "componentId": "footer-dLvoLZ16",
        "componentIndex": 9,
        "componentName": "app-builder-footer",
      },
      null
    ],
    "name": "Home"
  },
  {
    "components": [
      null,
      {
        "componentId": "navbar-UBdYplVp",
        "componentIndex": 1,
        "componentName": "app-builder-navbar",
      },
      null,
      {
        "componentId": "features-mmEzByeO",
        "componentIndex": 3,
        "componentName": "app-builder-features"
      },
      null,
      {
        "componentId": "features-GZKgh9lV",
        "componentIndex": 5,
        "componentName": "app-builder-features"
      },
      null,
      {
        "componentId": "footer-IyrNODRQ",
        "componentIndex": 9,
        "componentName": "app-builder-footer",
      },
      null
    ],
    "name": "About"
  }
]

4 个答案:

答案 0 :(得分:1)

看起来您在错误的对象上运行过滤器,请尝试以下操作:

注意:这还将修改传递到deleteNullComponents中的原始组件数组,因此在方法调用之后不必重新分配组件。如果您不希望出现这种情况,请查看以下线程:

How to deep clone an object in Javascript

class MyService {  
  static deleteNullComponents(components) {
    return components.map(obj =>
      obj["components"].filter(item => item !== null)
    )
  }
}

let pageComponents = [
  {
    "components": [
      null,
      {
        "componentId": "navbar-zJNm0HaP",
        "componentIndex": 1,
        "componentName": "app-builder-navbar",
      },
      null,
      null,
      null,
      {
        "componentId": "features-MJU8gcYR",
        "componentIndex": 5,
        "componentName": "app-builder-features",
      },
      null,
      {
        "componentId": "features-2hsUdwaT",
        "componentIndex": 7,
        "componentName": "app-builder-features",
      },
      null,
      {
        "componentId": "footer-dLvoLZ16",
        "componentIndex": 9,
        "componentName": "app-builder-footer",
      },
      null
    ],
    "name": "Home"
  },
  {
    "components": [
      null,
      {
        "componentId": "navbar-UBdYplVp",
        "componentIndex": 1,
        "componentName": "app-builder-navbar",
      },
      null,
      {
        "componentId": "features-mmEzByeO",
        "componentIndex": 3,
        "componentName": "app-builder-features"
      },
      null,
      {
        "componentId": "features-GZKgh9lV",
        "componentIndex": 5,
        "componentName": "app-builder-features"
      },
      null,
      {
        "componentId": "footer-IyrNODRQ",
        "componentIndex": 9,
        "componentName": "app-builder-footer",
      },
      null
    ],
    "name": "About"
  }
]

// no need to re-assign here, the original object is modified
pageComponents = MyService.deleteNullComponents(pageComponents)
console.log(pageComponents)

答案 1 :(得分:1)

componentspageComponents中的数组项中的一个数组属性

因此,您将需要两个循环(forEach / map / filter等实际上只是在遍历数组)

因此,对于pageComponents数组中的每个项目,您都希望过滤该项目的components属性中的值

此外,在过滤器函数中,您不需要返回原始数组,因为您没有更改原始数组,而是在其中更改了嵌套数组

class MyService {  
  static deleteNullComponents(components) {
    components.forEach(obj =>
      obj.components = obj.components.filter(item => item !== null)
    )
  }
}

let pageComponents = [
  {
    "components": [
      null,
      {
        "componentId": "navbar-zJNm0HaP",
        "componentIndex": 1,
        "componentName": "app-builder-navbar",
      },
      null,
      null,
      null,
      {
        "componentId": "features-MJU8gcYR",
        "componentIndex": 5,
        "componentName": "app-builder-features",
      },
      null,
      {
        "componentId": "features-2hsUdwaT",
        "componentIndex": 7,
        "componentName": "app-builder-features",
      },
      null,
      {
        "componentId": "footer-dLvoLZ16",
        "componentIndex": 9,
        "componentName": "app-builder-footer",
      },
      null
    ],
    "name": "Home"
  },
  {
    "components": [
      null,
      {
        "componentId": "navbar-UBdYplVp",
        "componentIndex": 1,
        "componentName": "app-builder-navbar",
      },
      null,
      {
        "componentId": "features-mmEzByeO",
        "componentIndex": 3,
        "componentName": "app-builder-features"
      },
      null,
      {
        "componentId": "features-GZKgh9lV",
        "componentIndex": 5,
        "componentName": "app-builder-features"
      },
      null,
      {
        "componentId": "footer-IyrNODRQ",
        "componentIndex": 9,
        "componentName": "app-builder-footer",
      },
      null
    ],
    "name": "About"
  }
]

MyService.deleteNullComponents(pageComponents)
console.log(pageComponents)

答案 2 :(得分:1)

您仅将一层移入该对象。假设您不关心name属性,则需要类似

的内容:
// take the array of objects and iterate over them
firstLevelArray.map((secondLevelArray) => {
  // grab each components array in the array of objects, and filter it for null
  return secondLevelArray['components'].filter((possibleComponent) => {
    return possibleComponent != null;
  })
});

但是您可能想要保留名称,无论如何,在假定当前数据结构的情况下,这是一种非常僵化的处理方式。这是一种快速且肮脏的递归方法,该方法应处理任意数量的嵌套...但是,递归在javascript中的实现并不完全正确。您应该使用下划线之类的库进行深度比较。我写这篇文章是出于娱乐和说明的目的,因为如果您不熟悉javascript,那么阅读库代码可能会有些困难(甚至对我的小脑袋来说也是如此)。

虽然可能已经很清楚了,但是我们正在做的是进入json中的每个项目,检查它是否为null,如果不是,则检查它是否为数组或对象:访问该数组的每个项目,依此类推。

let deepRemoveNull = function(x) { 
    if (x === null) {
        return;
    } 
    if (Array.isArray(x)) {
        let arr = [];
        for (const i of x) {
            if (x !== null) {
                let result = deepRemoveNull(i);
                // get rid of undefined
                if (result) {
                    arr.push(result);
                }
            }
        }
        return arr;
    } else if (typeof x === 'object') {
        let obj = {};
        for (const key in x) {
            if (x[key] !== null) {
                let result = deepRemoveNull(x[key]);
                // get rid of undefined
                if (result) {
                    obj[key] = result;
                }
            }
        }
        return obj;
    }
    return x;
}

如果将对象传递给上面的函数,则它应该对您有用。请勿在生产代码中使用以上

答案 3 :(得分:-2)

您可以使用单线:

components = components.filter(function(el) { return el !== null });