RRGT19
RRGT19

Reputation: 1677

Extract a property inside of an array of objects which is inside of another array of objects and have the result as an array of strings

I have a TypeScript array of objects with the following structure:

const surveyResponses: any[] = [
  {createdAt: new Date(), responses: [{questionId: 'input1', response: 'Bla'}]},
  {createdAt: new Date(), responses: [{questionId: 'input1', response: 'Blo'}]}
];

I would like to extract the response property inside of the responses array and have them as a single array of strings.

Expected result: ['Bla', 'Blo']

I have tried to follow these advices:

  1. From an array of objects, extract value of a property as array
  2. Returning only certain properties from an array of objects in Javascript

I have tried to use reduce without luck:

responses.reduce((a, o) => (o.responses.map(r => r.response) && a.push(o.responses.map(r => r.response)), a), []);

I have tried to use map without luck:

responses.map(r => r.responses).map(r => r.map(r => r.response));
Result: [["Bla"], ["Blo"]]

Any help would be appreciated.

Upvotes: 2

Views: 644

Answers (2)

Rubydesic
Rubydesic

Reputation: 3476

In my opinion, an even simpler option using flatMap. You can always polyfill it if its not available.

const result = surveyResponses.flatMap(r => r.responses).map(r => r.response)
console.log(result)

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 370679

Use flatMap to take the responses array, take their response strings, and combine them:

const surveyResponses = [
  {createdAt: new Date(), responses: [{questionId: 'input1', response: 'Bla'}]},
  {createdAt: new Date(), responses: [{questionId: 'input1', response: 'Blo'}]}
];

const result = surveyResponses.flatMap(
  item => item.responses.map(
    ({ response }) => response
  )
);
console.log(result);

Also note that using any defeats the whole point of using TypeScript, since it effectively disables type-checking for that expression. When possible, either let TS infer the type of an expression automatically, or denote the type yourself manually when you need to. (In this case, TS can infer the type of surveyResponses automatically just fine)

If you can't use flatMap, you can spread into concat:

const surveyResponses = [
  {createdAt: new Date(), responses: [{questionId: 'input1', response: 'Bla'}]},
  {createdAt: new Date(), responses: [{questionId: 'input1', response: 'Blo'}]}
];

const result = [].concat(...surveyResponses.map(
  item => item.responses.map(
    ({ response }) => response
  )
));
console.log(result);

Upvotes: 4

Related Questions