Как очистить пустые объекты массива и перенумеровать их? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть объект 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 голосов
/ 12 сентября 2018

Прежде всего, есть проблема с вашим вопросом, так как определение вашего первого объекта не проходит 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];

Это не очень понятно.

Самый ясный способ - использовать другой объект и заполнять следующий элемент, только если оригинал имеет значение, начиная с нулевого индекса и увеличивая его.

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; 
}

См. мою скрипку JS, которая показывает это .

Вы также можете использовать метод keys () объекта, чтобы получить массив имен ключей в том порядке, в каком вы получите их от итератора. Для массива вы можете использовать соединение (0, idx), чтобы удалить этот элемент.

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

Или вы можете использовать разбиение, но тогда вам придется работать «назад», иначе цикл for не будет работать правильно. Итак, сначала получите имена, а затем продолжайте работать с последним до первого всплывающего окна.

0 голосов
/ 12 сентября 2018

Это мое предложение. Также не используйте индекс в объявлениях массива: [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']}
0 голосов
/ 12 сентября 2018

Принимая массивы в качестве свойств, вы можете фильтровать по длине (с назначением деструктурирования ) и назначать этот массив объекту.

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

console.log(clean);
0 голосов
/ 12 сентября 2018

Предполагая, что значение индекса неявно

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

const newData = {};

for (const property in data) {
    if (data[property].length !== 0) {
        newData[property] = data[property]
    }
}

console.log(newData)
0 голосов
/ 12 сентября 2018

Я рекомендую использовать 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);
...