JS Reduce - сумма только длины массива в объекте - PullRequest
4 голосов
/ 28 июня 2019

У меня есть следующая структура данных:

const arr = [    
    {key: 0, x: [], y: []},
    {key: 0, x: [], y: []}
]

Я хочу проверить, все ли массивы пусты, у меня есть, как я могу сделать это, используя Reduce?Мой код пока:

arr.reduce((count, acc) => {
    return acc !== 'key' ? count + acc.length : count
}, 0)

Ответы [ 6 ]

3 голосов
/ 28 июня 2019

Вы можете взять key из объекта и проверить всю длину на наличие нуля.

const
    array = [{ key: 0, x: [], y: [] }, { key: 0, x: [], y: [] }],
    allZero = array.every(({ key, ...o }) =>
        Object.values(o).every(({ length }) => !length));

console.log(allZero);

Суммирование

const
    array = [{ key: 0, x: [], y: [] }, { key: 0, x: [], y: [] }],
    sum = array.reduce((s, { key, ...o }) =>
        Object.values(o).reduce((t, { length }) => t + length, s), 0);

console.log(sum);
1 голос
/ 28 июня 2019

Поскольку acc будет объектом в массиве, вы должны проверить свойства объекта, которые являются массивами.Используйте для этой цели Object.values, а также еще один reduce для массивов внутри каждого объекта и исключите key:

const arr = [    
    {key: 0, x: [], y: []},
    {key: 0, x: [], y: []}
];

const res = arr.reduce((a, { key, ...c }) => a + Object.values(c).reduce((e, { length: f }) => e + f, 0), 0);
console.log(res);
1 голос
/ 28 июня 2019

reduce немного неуклюжий способ сделать это, и вы зацикливаетесь на элементах массива, а не на ключах, как (я думаю) вы ожидали.

Используйте Array.every вместо:

const arr = [    
    {key: 0, x: [], y: []},
    {key: 0, x: [], y: []}
]

const arr2 = [    
    {key: 0, x: [1,2,3], y: []},
    {key: 0, x: [], y: []}
]

function areAllEmpty(a){
    return a.every(i => i.x.length == 0 && i.y.length == 0); 
}

console.log(areAllEmpty(arr));
console.log(areAllEmpty(arr2));
0 голосов
/ 28 июня 2019

Array.every - лучший вариант. Вы можете перебрать все значения объектов и проверить, являются ли они массивами, и, если они есть, вернуть false, если они не пусты. every остановит , как только найдет непустой массив , или завершит итерацию, в зависимости от того, что наступит раньше.

const arr = [    
  {key: 0, x: [], y: []},
  {key: 0, x: [], y: []}
];

const arr2 = [    
  {key: 0, x: [], y: [1]},
  {key: 0, x: [], y: []}
];

const allEmpty = (arr) => arr.every(el => {
  for (let v of Object.values(el)) {
    if (Array.isArray(v) && v.length > 0) return false;
  }
  return true;
});

console.log(allEmpty(arr));
console.log(allEmpty(arr2));
0 голосов
/ 28 июня 2019

Сумма только длины массивов в объекте с использованием Array.reduce():

const arr = [    
    {key: 0, x: [], y: [], abc: "hsgg" },
    {key: 0, x: [1, 2, 3, 4], y: [1, 2]}
];

const c = arr.reduce((count, obj) => {
    Object.values(obj).forEach(v => {
      if(Array.isArray(v)) count += v.length;
    });
    return count;
}, 0);

console.log(c);

Обратите внимание, что в других ответах длины строк также учитываются

0 голосов
/ 28 июня 2019

Вы можете использовать filter() на Object.values, чтобы получить только значения массива.А затем flat() и добавьте длину к результату

const arr = [    
    {key: 0, x: [], y: []},
    {key: 0, x: [], y: []}
]

let res = arr.reduce((count, acc) => {
    return count + Object.values(acc).filter(x => x.constructor === Array).flat().length
}, 0)

console.log(res)
...