如何清理空数组对象并重新编号?

时间:2018-09-12 16:46:16

标签: javascript arrays javascript-objects

我有一个JavaScript对象,例如

{0: [], 1: [0: 'a', 1: 'b'], 2: [], 3: [0: '20']}

我想摆脱该对象中的空插槽并重新编号其余的插槽,因此它具有正常顺序(0、1、2)。

我使用此功能:

function clean(obj) {
    for (var propName in obj) {
        if (obj[propName] === null || obj[propName].length == 0 || obj[propName] === undefined) {
            delete obj[propName];
        }
    }
}

哪个清除了对象,但随后我得到了

{1: [0: 'a', 1: 'b'], 3: [0: '20']}

但是我如何使1变为0和3变为1?

5 个答案:

答案 0 :(得分:1)

我建议使用Array而不是Object,但是您可以执行以下操作:

var obj = {0: [], 1: ['a', 'b'], 2: [], 3: ['20']};

var newObj = Object.keys(obj).reduce(function (acc, k) {
  var objVal = obj[k];
  if (objVal.length) {
    acc[Object.keys(acc).length] = objVal;
  }
  return acc;
}, {});

console.log(newObj);

答案 1 :(得分:1)

假设数组为属性,则可以按长度过滤(使用destructuring assignment),然后将此数组分配给对象。

var data = { 0: [], 1: ['a', 'b'], 2: [], 3: ['20'] },
    clean = Object.assign({}, Object.values(data).filter(({ length }) => length));

console.log(clean);

答案 2 :(得分:1)

首先,您的问题出了问题,因为第一个对象的定义未通过JS编译。数组元素被赋予了带有索引的“键”,您编写了... 1: [0: 'a', 1: 'b'],它应该是:

1: {0: 'a', 1: 'b'}

1: ['a','b']

您显然在数组的索引和对象keys之间混在一起。

在这里,您为对象键指定了它们在数组中的索引的名称。因此,也许您在问三个问题之一。 (我会分别回答):

// 1. Clean [[], ['a','b'], [], '20']
// returning: [['a','b'], ['20']]  
// and not using params at all. 

// 2. Clean {0: [], 1: ['a','b'], 2: [], 3: ['20']}
// returning: {0: ['a','b'], 1: ['20']}

// 3. Clean {0: {}, 1: {0: 'a', 1: 'b'}, 2: {}, 3: {0: '20'}}
// returning: {0: {0: 'a', 1:'b'}, 1: {0: '20'}}

使功能保持完整的最快方法是在功能底部添加一个新的“索引器”,以更正键。我们可以按以下方式使用ES6:

 // if to delete...
 let oldKey = paramName;
 let newKey = (obj.keys().indexOf(oldKey)) - 1;
 delete obj[oldKey].assign(o, {[newKey]: o[oldKey] })[oldKey];

这不是很清楚。

最清晰的方法是使用另一个对象并仅在原始对象具有值时填充下一个元素,该值从索引0开始并增加它。

function cleanup(obj) {
  let newObj = {};
  let idx = 0;
  for (var propName in obj) {
    let prop = obj[propName];
    console.log('prop', propName, JSON.stringify(prop))

    if (prop !== null 
     && prop !== undefined
     && JSON.stringify(prop) != "[]" // not empty array
     && JSON.stringify(prop) !== "{}") { // not empty obj
      newObj[idx] = prop;
      idx++;
    }
  }
  return newObj; 
}

请参见my JS fiddle which shows this

您还可以使用对象的keys()方法按从迭代器获取键名的顺序获取键名数组。对于数组,您可以使用splice(0,idx)删除该元素。

https://www.w3schools.com/js/js_array_methods.asp

或者您可以使用拆分,但随后必须“向后”工作,否则for循环将无法正常工作。因此,首先获取属性名称,然后随着您的操作从最后一个到第一个弹出窗口工作。

答案 3 :(得分:0)

假设索引值是隐式的

{path: 'reset-password/:token', component: ResetPasswordComponent}

答案 4 :(得分:0)

这是我的建议。也不要在数组声明中使用索引:[0: 'a', 1: 'b']应该为['a', 'b']

const data = {0: [], 1: ['a', 'b'], 2: [], 3: ['20']};

const dataArray = Object.values(data);
let result = {};
let index = 0;

dataArray.forEach(d => {
  if (d.length) Object.assign(result, {[index++]: d});
})

// result --> {0: ['a', b'], 1: ['20']}