2

I have an array of Foo called fooArray, but I would like to map() the array to only contain the “key: value” pairs which are defined in arrayOfKeys.

class Foo {
  id: number;
  name: string;
  age: number;

  constructor(id: number, name: string, age: number) {
    this.id = id;
    this.name = name;
    this.age = age;
  }
}

let fooArray: Foo[] = [
  new Foo(1, 'Foo', 20), 
  new Foo(2, 'Bar', 21),
  new Foo(3, 'MyFoo', 20)
  ];


//The keys I would like to select from Foo.
const arrayOfKeys: (keyof Foo)[] = ['name', 'age'];  

I do not know what to do to get the desired result below:

// The result is a copy of 'fooArray', but the objects only 
// contain the keys (and their values) defined in 'arrayOfKeys'.
[
   { name: 'Foo', age: 20 },
   { name: 'Bar', age: 21 },
   { name: 'MyFoo', age: 20 }
]
1
  • 1
    You probably want array.filter not array.map? Commented Aug 13, 2021 at 8:16

5 Answers 5

4

You can probably do this by creating a new object in the map and returning it?

Something like

const fooArrayWithLimitedKeys = fooArray.map(item => arrayOfKeys.reduce(
  (accumulator, key) => {
    accumulator[key] = item[key]
    return accumulator
  }, {})
)

it can also be written without reduce like follows:

const fooArrayWithLimitedKeys = fooArray.map(item => {
  const returnValue = {}
  arrayOfKeys.forEach(key => {
    returnValue[key] = item[key]
  })
  return returnValue;
})
Sign up to request clarification or add additional context in comments.

Comments

1

Considering you simply want to modify each item of your array of objects to only contain desired keys, you may go like that:

const src = [
   { id: 1, name: 'Foo', age: 20 },
   { id: 2, name: 'Bar', age: 21 },
   { id: 3, name: 'MyFoo', age: 20 }
]

const keys = ['name', 'age']

const result = src.map(item => Object.assign(
  ...keys.map(key => ({[key]: item[key]}))
))

console.log(result)

1 Comment

Works perfectly in JavaScript but sadly it doesn't work in TypeScript. Error: TS2556: A spread argument must either have a tuple type or be passed to a rest parameter
0

You can use Object Destructuring, inside a map function, something like that.

class Foo {
  id: number;
  name: string;
  age: number;

  constructor(id: number, name: string, age: number) {
    this.id = id;
    this.name = name;
    this.age = age;
  }
}

let fooArray: Foo[] = [
  new Foo(1, 'Foo', 20), 
  new Foo(2, 'Bar', 21),
  new Foo(3, 'MyFoo', 20)
  ];
const arrayOfKeys: (keyof Foo)[] = ['name', 'age'];  

const result = fooArray.map(element =>(({name,age}) => ({name,age}))(element));
console.log(result);

Comments

0

First of all: if you don't really need to reassign fooArray further in code I would recommend it be a const.

Then you can add something like pick function, if you don't want to use lodash or underscore:

function pick(object: any, keys: string[]) {
    return keys.map((key: string) => ({ [key]: object[key] }))
}

And use it like this:

const res = fooArray.map(el => pick(el, arrayOfKeys))

Comments

0

Your can create generic function which will accept target array and array of fields to be extracted. You should loop on desired fields and save them to result object. Heres solution in TypeScript:

Generic function

function mapToLimitedProps<A, Keys extends (keyof A)[]>(arr: A[], keys: Keys) {
    return arr.map(item => {
        let result: Partial<{
            [key in Keys[number]]: A[key]
        }> = {};

        keys.forEach(key => {
            result[key] = item[key];
        })

        return result;
    })
}

Usage

mapToLimitedProps(fooArray, arrayOfKeys);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.