Создание массива из ненулевых свойств объекта Javascript / typescript

Ваша ошибка возникает из-за того, что .className возвращает живой HTMLCollection. Поэтому, когда вы делаете что-то вроде этого:

blockSet[0].className = "block-selected";

Ваша коллекция blockSet[0] станет blockSet[1]. Поэтому, когда вы выполняете строку:

blockSet[1].className = "block-selected";

Вы не меняете blockSet[1], который вы думаете, но вы меняете стартовый blockSet[2].

Итак, вы можете сделать это:

var blockSet = document.getElementsByClassName("block-default");
var blockSetLength = blockSet.length;
for(var i=0;i

http://jsfiddle.net/94dqffa7/

Я думаю, что это лучший способ сделать это. Поскольку classList.add() и classList.remove() помогут вам изменить свой класс, не выбирая класс других, которые у вас есть на вашем div (если у вас есть). Кроме того, вам нужно добавить новый, прежде чем удалить старый, или у вас будет такая же проблема, как и раньше.

0
задан prabhat gundepalli 13 July 2018 в 20:37
поделиться

3 ответа

Вы можете использовать Object.entries() для получения пар имя-значение, затем сопоставить их с объектами:

Object.entries(obj)
    .filter(([name, value]) => value !== null)
    .map(([name, value]) => ({name, value}));
4
ответ дан SLaks 17 August 2018 в 12:31
поделиться
  • 1
    Легко читается и, поскольку он использует собственные методы, должен быть хорошо оптимизирован. +1 – Nikola Geneshki 13 July 2018 в 15:24
  • 2
    Благодарю. Я чувствовал, что это самый оптимизированный подход среди ответов здесь. – prabhat gundepalli 13 July 2018 в 17:06
  • 3
    @prabhatgundepalli Я подумал, что тот факт, что мой ответ выполнял одну полную итерацию свойств объекта, должен означать, что он был более оптимальным. Я был неправ. Кстати, я предоставил дополнительный подход, используя только reduce, и он превосходит этот ответ более чем на 20% в моем AMD Athlon II X3 450, Firefox 61 и Linux Mint 18.3. – Matías Fidemraizer 15 July 2018 в 14:38
  • 4

Вы можете просто использовать Object.entries() и Array.reduce()

var fields = {
  "name":"andy",
  "age" : null,
  "email" : null,
  "status" : true
};

var result = Object.entries(fields).reduce((a,[key,val])=>{
  if(val)
    a.push({name : key, value : val});
  return a;
},[]);

console.log(result);

Выход:

[
  {
    "name": "name",
    "value": "andy"
  },
  {
    "name": "status",
    "value": true
  }
]
1
ответ дан amrender singh 17 August 2018 в 12:31
поделиться

Один из возможных подходов:

const obj = { a: 1, b: null, c: 2, d: null }

const output = Object.entries (obj)
                     .reduce ((a, [k, v]) => v !== null ? [...a, [k, v]] : a, [])
      
console.log(output)

Тот же подход с локальной мутацией

Вот такой же подход с использованием локальной мутации из Array#reduce -коммулятора, который является более оптимальным.

Поскольку Array#reduce получает уже выделенный массив с N пустым слотом (где N является общее количество ключей во входном объекте), массив никогда не требует внутренней операции для увеличения своей длины. После того, как записи объекта уменьшены, мы отфильтровываем неопределенные элементы (те, что были null):

const obj = {
  a: 1,
  b: null,
  c: 2,
  d: null
}

const keyCount = Object.keys(obj).length

const output = Object.entries(obj)
  .reduce((a, kvp, i) => {
    if (kvp[1] !== null) a[i] = kvp
    return a
  }, Array(keyCount))
  .filter(kvp => kvp)

console.log(output)

JSPerf perf test фильтр + карта против уменьшения + фильтр

1
ответ дан Matías Fidemraizer 17 August 2018 в 12:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: