Extract and Transform Data with TypeScript
You're tasked with creating a robust helper function in TypeScript that can extract specific pieces of information from a given data structure and transform them into a desired format. This is a common requirement in data processing, API integration, and front-end development where you need to shape data for display or further processing.
Problem Description
Your goal is to implement a TypeScript function called extractAndTransform that takes three arguments:
data: The source data structure (can be an object, array, or primitive).selectors: An array of functions, where each function represents a "selector". A selector takes thedataas input and returns a specific value or nested structure from it.transformer: A function that takes an array of extracted values (corresponding to the order of selectors) and transforms them into a single, final output.
The extractAndTransform function should:
- Apply each
selectorfunction in theselectorsarray to thedata. - Collect the results from each selector in the order they appear.
- Pass the collected results as an array to the
transformerfunction. - Return the value returned by the
transformerfunction.
Key Requirements:
- The function must be written in TypeScript.
- The function should be generic enough to handle various data types for
data, selector return types, and the final transformed output. - The order of results passed to the
transformermust match the order ofselectors.
Expected Behavior:
If data is { user: { name: 'Alice', age: 30 } }, selectors are [data => data.user.name, data => data.user.age], and transformer is ([name, age]) => \Name: ${name}, Age: ${age}`, the function should return "Name: Alice, Age: 30"`.
Edge Cases:
- What happens if
selectorsis an empty array? Thetransformershould still be called, likely with an empty array. - What happens if a selector returns
undefinedornull? Thetransformershould receive these values.
Examples
Example 1:
const userData = {
profile: {
firstName: 'Bob',
lastName: 'Smith',
contact: {
email: 'bob.smith@example.com',
phone: '123-456-7890'
}
},
isActive: true
};
const selectors = [
(data: typeof userData) => data.profile.firstName,
(data: typeof userData) => data.profile.contact.email,
(data: typeof userData) => data.isActive
];
const transformer = (values: [string, string, boolean]) => {
return {
fullName: values[0],
contactInfo: values[1],
status: values[2] ? 'Active' : 'Inactive'
};
};
// Expected Output:
// {
// fullName: 'Bob',
// contactInfo: 'bob.smith@example.com',
// status: 'Active'
// }
Example 2:
const productList = [
{ id: 1, name: 'Laptop', price: 1200 },
{ id: 2, name: 'Mouse', price: 25 },
{ id: 3, name: 'Keyboard', price: 75 }
];
const selectors = [
(data: typeof productList) => data.length, // Number of products
(data: typeof productList) => data.filter(p => p.price > 100).map(p => p.name) // Names of expensive products
];
const transformer = (values: [number, string[]]) => {
return `Total products: ${values[0]}, Expensive products: ${values[1].join(', ')}`;
};
// Expected Output:
// "Total products: 3, Expensive products: Laptop"
Example 3: Edge Case - Empty Selectors
const data = { message: 'Hello' };
const selectors: [] = []; // Empty array of selectors
const transformer = (values: []) => {
return "No data extracted.";
};
// Expected Output:
// "No data extracted."
Constraints
- The
extractAndTransformfunction should accept an arbitrary number of selectors. - The
dataargument can be any JavaScript value (object, array, primitive, null, undefined). - The
selectorsarray will contain functions. - The
transformerfunction will accept an array of values and return a single value. - The solution must use TypeScript with appropriate type annotations for strong typing.
Notes
- Consider how you will handle the types for the
selectorsandtransformerfunctions to make theextractAndTransformfunction as flexible and type-safe as possible. - Think about the return type of the
extractAndTransformfunction itself. - The core of this challenge lies in correctly typing the generic parameters.