Home > Software design >  Use 2 filter in array java script
Use 2 filter in array java script

Time:12-04

I have an array like this

I would like to bring only the installments with checked = true and with payments checked = true

I have this array

 0: {
    checked: true,
    code: 100.
    paymant: Array(2)
    {
        0: {data: 03/12/2021, checked: true},
        1: {data: 03/12/2021}
    }
 },
  1: {
    code: 100.
    paymant: Array(2)
    {
        0: {data: 03/12/2021},
        1: {data: 03/12/2021}
    }
 }

// Real Data
const data = [
    {
        checked: true,
        code: 100,
        payments: [
            {data: 'checked', checked: true},
            {data: 'not-checked'}
        ]
    },
    {
        code: 100,
        payments: [
            {data: 'not-checked'},
            {data: 'not-checked'}
        ]
    }
];

I would like this

0: {
    checked: true,
    code: 100.
    paymant: Array(1)
    {
        0: {data: 03/12/2021, checked: true},
    }
 },

I try to do this but no work

 installments.filter(i => i.checked).filter(i => i.paymant.filter(p => p.checked))

CodePudding user response:

The first filter is straight forward but you'll need to rebuild the payments array so it only contains the checked entry.

const data = [
    {
        checked: true,
        code: 100,
        payments: [
            {data: 'checked', checked: true},
            {data: 'not-checked'}
        ]
    },
    {
        code: 100,
        payments: [
            {data: 'not-checked'},
            {data: 'not-checked'}
        ]
    }
];

const checked = (item) => item && item.checked;
const paymentCheckedMapper = (item) => (
    {...item, payments: item.payments.filter(checked)}
);

data.filter(checked).map(paymentCheckedMapper)

https://jsfiddle.net/vebwfnL0/

CodePudding user response:

Since you need to mix and match filter and map. You can use reduce here. No need to filter then map, It will cost performance issues.

const data = [
  {
    checked: true,
    code: 100,
    paymant: [
      { data: 03 / 12 / 2021, checked: true },
      { data: 03 / 12 / 2021 },
    ],
  },
  {
    code: 101,
    paymant: [{ data: 03 / 12 / 2021 }, { data: 03 / 12 / 2021 }],
  },
];

const getPaid = (records = []) => {
  return records.reduce((acc, record) => {
    if (!record.checked) return acc;
    const paymant = record.paymant.filter((paymant) => paymant.checked);
    if (paymant.length) {
      acc.push({ ...record, paymant });
    }
    return acc;
  }, []);
};
console.log(getPaid(data));
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You can archive this in a single pass using reduce instead filter

const filtered = installments.reduce((filtered, item) => {
  if (item.checked && item.paymant.some(value => value.checked)) {
    return [...filtered, item]
  }
  return filtered
}, [])

OR even better using single filter

const filtered = installments.filter((item) => {
  return item.checked && item.paymant.some(value => value.checked))
}, [])
  • Related