Reputation: 14404
I'm developing with Angular and I have the following Typescript array of objects:
docs = [
{
id: '1',
type: {
id: 1
desc: 'Category 1',
}
title: 'Foo",
date: '2018-06-21',
attachments: [
{ id: 51, filename: 'foo.pdf', title: 'Foo' },
{ id: 20, filename: 'bar.doc', title: 'Bar' }
]
},
{
id: '2',
type: {
id: 2
desc: 'Category 2',
}
title: 'Bar",
date: '2018-06-21',
attachments: [
{ id: 15, filename: 'foobar.xls', title: 'Foobar' },
{ id: 201, filename: 'example.doc', title: 'Example' }
]
}
]
I need to get only a subset of the properties, something like this:
docs = [
{
id: '1',
type: {
id: 1
desc: 'Category 1',
}
attachments: [
{ id: 51 },
{ id: 20 }
]
},
{
id: '2',
type: {
id: 2
desc: 'Category 2',
}
attachments: [
{ id: 15 },
{ id: 201 }
]
}
]
How can I achieve this? Have I to create a parser or does exist any smart way (such as Lodash) to extract a lite version of the array?
Upvotes: 4
Views: 4616
Reputation: 1918
var docs = [{"id":"1","type":{"id":1,"desc":"Category 1"},"title":"Foo","date":"2018-06-21","attachments":[{"id":51,"filename":"foo.pdf","title":"Foo"},{"id":20,"filename":"bar.doc","title":"Bar"}]},{"id":"2","type":{"id":2,"desc":"Category 2"},"title":"Bar","date":"2018-06-21","attachments":[{"id":15,"filename":"foobar.xls","title":"Foobar"},{"id":201,"filename":"example.doc","title":"Example"}]}];
const result = docs.map(({id,type,attachments})=>{
let doc={id,type};
doc.attachments=attachments.map(({id})=>({id}));
return doc;
});
console.log(result);
have a look at this. this works perfectly!
Upvotes: 4
Reputation: 3115
I was looking for a non-specific way to accomplish this or any other similar cases, so far I've thought of the following:
IMapping<T>
type, that defines the way to map each property.IMappingFunction<T>
interface, that determines how to map a specific thing:The following code demonstrates it:
type IMapping<T> = {
[P in keyof T]: IMapping<T[P]> | IMappingFunction<T[P]>;
}
interface IMappingFunction<T>{
(t: T): T | Partial<T>
}
class Person{
name: string;
lastName: string;
}
const obj: IMapping<Person> = {
name: s => s.toUpperCase(),
lastName: s => s
}
function map<T>(obj: T, mapping: IMapping<T>) {
return Object.keys(obj)
.map(prop => {
const propMapping = mapping[prop];
return {
key: prop,
value: typeof propMapping === 'function' ?
propMapping(obj[prop]) :
map(obj, propMapping)
};
})
.reduce((acc, prop) => ({...acc, [prop.key]: prop.value}), { });
}
console.log(map({ name: 'Name', lastName: 'LastName'}, obj));
For a runnable snippet check here
Upvotes: 0
Reputation: 4879
You can use Array.map
with object spreading, something like this:
const mapSubset = ({ id, type, attachments }) => {
return { id, type, attachments: attachments.map( {id} => id ) };
};
const subset = docs.map( mapSubset );
Upvotes: 1
Reputation: 11
You can use array.map and object destructuring to extract only the wanted properties.
Also use JSON.parse and JSON.stringify to make a copy and avoid side effetcs.
docs2 = JSON.parse(JSON.stringify(docs)).map(
({id, type, attachements}) =>
({ id,
type,
attachements: attachements.map(({id}) => ({id})
})
)
Upvotes: 1
Reputation: 398
do you need to leave the original array intact? If not you can iterate through the list of objects using a for loop and use the 'delete' operator to delete the properties you no longer want.
For example:
var Employee = {
firstname: "Mohammed",
lastname: "Haddad"
}
delete Employee.firstname;
console.log(Employee);
// expected output: { lastname: "Haddad" }
Upvotes: -2