Как отфильтровать массив на основе фильтрации внутреннего свойства массива? - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть следующий массив объектов:

let a = [
    {
        b: [1, 11, 12],
        c: "a1"
    },
    {
        b: [2, 56, 1],
        c: "a2"
    },
    {
        b: [1, 2, 3],
        c: "a3"
    }
]

Я хочу сделать простейшую операцию, где я могу вернуть второй массив , который является копией из a, но включает в себя только элементы, массив которых b содержит хотя бы один элемент больше 10, и для каждого такого элемента b содержит только те элементы, которые больше 10.Поэтому я хочу, чтобы результат был:

[
    {
        b: [11, 12],
        c: "a1"
    },
    {
        b: [56],
        c: "a2"
    }
]

Я знаю, что мог бы сделать это наивно с циклами или несколькими шагами, используя filter(), но мне интересно, есть ли эффективное однострочное решение.Любые советы?

Ответы [ 8 ]

0 голосов
/ 02 февраля 2019

Поскольку никто не упомянул об этом, вот один из подходов, использующих вложенные filters().

. Я основал этот подход на условии, что если массив b имеет некоторый элемент больше 10, торезультат фильтрации по предыдущему условию даст в результате массив non-empty.

Также обратите внимание, что это не изменяет исходный массив, потому что он изменяет копию массива, который получают фильтры.

let a = [
    {b: [1, 11, 12], c: "a1"},
    {b: [2, 56, 1], c: "a2"},
    {b: [1, 2, 3], c: "a3"}
]

let res = a.filter(
    ({b}, i, arr) => (arr[i].b = b.filter(x => x > 10)) && arr[i].b.length > 0
);

console.log(res);
0 голосов
/ 01 февраля 2019

ОБНОВЛЕНИЕ Здесь есть множество хороших ответов (я до сих пор голосовал за всех).Вот что я в итоге придумала:

a.filter(x => x.b.some(y => y>10)).map((z) => {
    return {
        b: z.b.filter(zb => zb>10),
        c: z.c
    }
})

Объяснение:

Вы берете «a» и фильтруете его, чтобы включить только те элементы, для которых «b» имеет «некоторый элемент».у такой, что у> 10 '.Таким образом, в этот момент вы бы отфильтровали третий элемент «a», так как в его «b» нет элементов, которые> 10. Теперь у вас есть это:

[
    {
        b: [1, 11, 12],
        c: "a1"
    },
    {
        b: [2, 56, 1],
        c: "a2"
    }
]

Следующая картаэтот новый массив, т.е.для каждого элемента вы возвращаете новый элемент в новом массиве, который имеет то же значение 'c' и то же значение 'b', за исключением того, что фильтруется, чтобы включить только те элементы, которые> 10. Таким образом, вы получите:

[
    {
        b: [11, 12],
        c: "a1"
    },
    {
        b: [56],
        c: "a2"
    }
]

Спасибо за ваш вклад!

0 голосов
/ 01 февраля 2019

Другие отличные ответы здесь.Мой дубль:

var ans = a.slice().filter(item => {
    item.b = item.b.filter(s => s > 10)
  return (item.b.length > 0) ? true : false;
})
0 голосов
/ 01 февраля 2019
let result = a.map((rec)=> {rec.b.filter((bRec)=>bRec>10), rec.c}).filter((rec)=>rec.b.length == 0);
0 голосов
/ 01 февраля 2019

Вот простой способ сделать это.

let a = [
    {
        b: [1, 11, 12],
        c: "a1"
    },
    {
        b: [2, 56, 1],
        c: "a2"
    },
    {
        b: [1, 2, 3],
        c: "a3"
    }
]

var result = [];
a.forEach((item) => {
var subItem = { c:item.c, b: item.b.filter((b)=> b > 10)}
if (subItem.b.length>0)
     result.push(subItem);
});

console.log(result)
0 голосов
/ 01 февраля 2019

Вы можете использовать уменьшить и фильтровать

let a = [{b: [1, 11, 12],c: "a1"},{b: [2, 56, 1],c: "a2"},{b: [1, 2, 3],c: "a3"}]


let op = a.reduce((out,{b,c})=>{
  let temp = b.filter(e => e > 10);
  if(temp.length){
    out.push( { b : temp,c })
  } 
  return out
},[])

console.log(op)
0 голосов
/ 01 февраля 2019

Вы можете использовать .filter() и .map(), чтобы получить желаемый результат:

let a = [{
    b: [1, 11, 12],
    c: "a1"
}, {
    b: [2, 56, 1],
    c: "a2"
}, {
    b: [1, 2, 3],
    c: "a3"
}];

let b = a.filter(({ b }) => b.some(v => v > 10))
         .map(o => Object.assign({}, o, {b: o.b.filter(v => v > 10)}));

console.log(b);
.as-console-wrapper {max-height: 100% !important; top: 0; }
0 голосов
/ 01 февраля 2019

Вы можете использовать filter и reduce следующим образом:

let a = [{b:[1,11,12],c:"a1"},{b:[2,56,1],c:"a2"},{b:[1,2,3],c:"a3"}]

const output = a.reduce((acc, { b, c }) => {
  // filter "b" property
  const filtered = b.filter(n => n > 10);
  
  if (filtered.length)
    acc.push({ b: filtered, c });
    
  return acc;
}, [])

console.log(output)
...