简体   繁体   中英

How to filter array of object and filter out values based on another array? Filtering should happen based on keys not values

I have an array of object which must be filtered based on another array, the keys are listed in the allowed array, pls help tired using object.entries and reduce but didn't work

const filter = _.filter;
const data = [{
    id: 1,
    row: [{
        id: 'a',
        name: 'ab',
        code: 'sdf',
        version: 1
      },
      {
        id: 'b',
        name: 'bc',
        code: 'def',
        version: 3
      },
      {
        id: 'c',
        name: 'cd',
        code: 'afd',
        version: 2
      },
    ]
  },
  {
    id: 2,
    row: [{
        id: 'd',
        name: 'ef',
        code: 'sdf',
        version: 1
      },
      {
        id: 'e',
        name: 'gh',
        code: 'def',
        version: 3
      },
      {
        id: 'f',
        name: 'ij',
        code: 'afd',
        version: 2
      },
    ]
  },
  {
    id: 3,
    row: [{
        id: 'g',
        name: 'kl',
        code: 'asd',
        version: 2
      },
      {
        id: 'h',
        name: 'mn',
        code: 'faf',
        version: 3
      },
      {
        id: 'i',
        name: 'op',
        code: 'dfs',
        version: 1
      },
    ]
  }
]

const allowed = ['id', 'name']

let result = [{
    id: 1,
    row: [{
        id: 'a',
        name: 'ab'
      },
      {
        id: 'b',
        name: 'bc'
      },
      {
        id: 'c',
        name: 'cd'
      },
    ]
  },
  {
    id: 2,
    row: [{
        id: 'd',
        name: 'ef'
      },
      {
        id: 'e',
        name: 'gh'
      },
      {
        id: 'f',
        name: 'ij'
      },
    ]
  },
  {
    id: 3,
    row: [{
        id: 'g',
        name: 'kl'
      },
      {
        id: 'h',
        name: 'mn'
      },
      {
        id: 'i',
        name: 'op'
      },
    ]
  }
]

result = data.filter(el => el.row.filter(elm => Object.fromEntries(allowed.map(k => [k, elm[k]]))));

console.log(result);

You can create a new array with Array.map .

Logic

  • Map through the array.
  • Just spread operator to seperate out row key and rest of keys.
  • return an object with rest of keys and row key as with the Object.fromEntries

 const data = [{ id: 1, row: [ { id: 'a', name: 'ab', code: 'sdf', version: 1 }, { id: 'b', name: 'bc', code: 'def', version: 3 }, { id: 'c', name: 'cd', code: 'afd', version: 2 }, ] }, { id: 2, row: [ { id: 'd', name: 'ef', code: 'sdf', version: 1 }, { id: 'e', name: 'gh', code: 'def', version: 3 }, { id: 'f', name: 'ij', code: 'afd', version: 2 }, ] }, { id: 3, row: [ { id: 'g', name: 'kl', code: 'asd', version: 2 }, { name: 'mn', code: 'faf', version: 3 }, { id: 'i', name: 'op', code: 'dfs', version: 1 }, ] } ] const allowed = ['id', 'name']; const result = data.map(({ row, ...rest }) => { return {...rest, row: row.map(elm => Object.fromEntries(allowed.map(k => [k, elm[k]]))) } }); console.log(result);

Long way but it works:

 const data = [ {id: 1, row: [ {id: 'a', name: 'ab', code: 'sdf', version: 1}, {id: 'b', name: 'bc', code: 'def', version: 3}, {id: 'c', name: 'cd', code: 'afd', version: 2}, ] }, {id: 2, row: [ {id: 'd', name: 'ef', code: 'sdf', version: 1}, {id: 'e', name: 'gh', code: 'def', version: 3}, {id: 'f', name: 'ij', code: 'afd', version: 2}, ] }, {id: 3, row: [ {id: 'g', name: 'kl', code: 'asd', version: 2}, {id: 'h', name: 'mn', code: 'faf', version: 3}, {id: 'i', name: 'op', code: 'dfs', version: 1}, ] } ]; const allowed = ['id', 'name']; let res = []; data.forEach((el) => { let obj = {}; obj.id = el.id; obj["row"] = []; let row = buildArray(el.row); obj["row"].push(row); res.push(obj); }) function buildArray(row) { r = {}; allowed.forEach((k) => { r[k] = row[0][k]; }) return r; } console.log(res)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM