'map array of objects based on set of properties

Suppose I have an object:

let array = [
  {a: 1, b: 5, c: 9},
  {a: 2, b: 6, c: 10},
  {a: 3, b: 7, c: 11},
  {a: 4, b: 8, c: 12}
];

then I have a dictionary:

const columns = [
  { key: 'a', value: 'a' },
  { key: 'b', value: 'b' },
]

I want to filter out properties that are not defined in columns.

I have tried

array.map((x) =>  ({"a": x.a, "b": x.b}))

Is there a way to use the data defined in columns instead of manually typing all the properties?

Desired output:

[
  {
    "a": 1,
    "b": 5
  },
  {
    "a": 2,
    "b": 6
  },
  {
    "a": 3,
    "b": 7
  },
  {
    "a": 4,
    "b": 8
  }
]


Solution 1:[1]

You could map entries and get the new objects.

let
    array = [{ a: 1, b: 5, c: 9 }, { a: 2, b: 6, c: 10 }, { a: 3, b: 7, c: 11 }, { a: 4, b: 8, c: 12 }],
    columns = [{ key: 'a', value: 'a' }, { key: 'b', value: 'b' }],
    keys = columns.map(({ key }) => key),
    result = array.map(o => Object.fromEntries(keys.map(k => [k, o[k]])));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Solution 2:[2]

You could use this.

This uses just an array to hold the desired columns because I don't get why you would use a dictionary with key and value being the same.

let array = [
  { a: 1, b: 5, c: 9 },
  { a: 2, b: 6, c: 10 },
  { a: 3, b: 7, c: 11 },
  { a: 4, b: 8, c: 12 },
];

const desiredColumns = ["a", "b"];

const transformed = array.map(item => {
    const obj = {};
    desiredColumns.forEach(col => {
        if(col in item){
            obj[col] = item[col];
        }
    })
    return obj;
})

console.log(array);
console.log(transformed)

Solution 3:[3]

Another, slightly less direct way using map() and reduce():

  1. Create an array with all the keys we'll keep
  2. Reduce the array to get the desired result
    • Add current key + value if key keep array

const array   = [{a: 1, b: 5, c: 9}, {a: 2, b: 6, c: 10}, {a: 3, b: 7, c: 11}, {a: 4, b: 8, c: 12} ];
const columns = [{ key: 'a', value: 'a' }, { key: 'b', value: 'b' }, ];

const toKeep = columns.map(({ key }) => key).flat();

const result = array.map(a => 
   Object.keys(a)
      .reduce((prev, cur) => (toKeep.includes(cur)) ? { ...prev, [cur]: a[cur] } : prev, {})
);

console.log(result);

Result:

[
  {
    "a": 1,
    "b": 5
  },
  {
    "a": 2,
    "b": 6
  },
  {
    "a": 3,
    "b": 7
  },
  {
    "a": 4,
    "b": 8
  }
]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nina Scholz
Solution 2 Mushroomator
Solution 3 0stone0