How to Get a Subset of a JavaScript Object's Properties

How to get a subset of a javascript object's properties

Using Object Destructuring and Property Shorthand

const object = { a: 5, b: 6, c: 7  };

const picked = (({ a, c }) => ({ a, c }))(object);

console.log(picked); // { a: 5, c: 7 }

How to get a subset of a javascript object's properties excluding undefined or null properties

Convert the object to entries and filter by:

  • Object property (key) exists in the desired key list (props)
  • Value (val) is not null.

const myObject1 = { 
color: 'red',
size : 'big',
name : 'Beautiful red',
count: 2
};

const myObject2 = {
color: 'blue',
name : 'Awesome blue',
count : null
};

function myHelper(obj, props) {
return Object.fromEntries(Object.entries(obj)
.filter(([key, val]) => props.includes(key) && val != null));
}

console.log(myHelper(myObject1, ['color','size','count']));
console.log(myHelper(myObject2, ['color','size','count']));
.as-console-wrapper { top: 0; max-height: 100% !important; }

How to create a new object as a subset of object properties of any depth, while renaming properties on the fly

You can do something like this

const select = (data, filters) => Object.entries(filters)
.reduce((res, [key, path]) => {
return {
...res,
[key]: path.reduce((current, segment) => current[segment] ?? undefined , data)
}

}, {})


const earthData = {
distanceFromSun: 149280000,
continents: {
asia: {
area: 44579000,
population: 4560667108,
countries: { japan: { temperature: 62.5 } },
},
africa: { area: 30370000, population: 1275920972 },
europe: { area: 10180000, population: 746419440 },
america: { area: 42549000, population: 964920000 },
australia: { area: 7690000, population: 25925600 },
antarctica: { area: 14200000, population: 5000 },
},
};

const earthDataSubset = select(earthData, {
distanceFromSun: ['distanceFromSun'],
asiaPop: ['continents', 'asia', 'population'],
americaArea: ['continents', 'america', 'area'],
japanTemp: ['continents', 'asia', 'countries', 'japan', 'temperature'],
});

console.log(earthDataSubset)

How to get a subset of a Javascript object with nested properties?

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);

How to get an subset of properties given as list in Javascript?

You can just map over each of the objects, and use Object.fromEntries to create a new object with the given keys:

const data = [

{ name: "John", age: "22", weight: "60", height: "180cm" },

{ name: "Emma", age: "25", weight: "55", height: "160cm" }

]

const keys = ["name", "weight", "height"]

const res = data.map(o => Object.fromEntries(keys.map(k => [k, o[k]])))

console.log(res)

Create a subset object, consisting of only some of the properties of an existing object

There is no specific syntax for this. You can keep doing:

var subsetObj = {a: o.a, c: o.c};

If you have more properties or a variable number of properties, create a helper function.

Related: Is it possible to destructure onto an existing object? (Javascript ES6)

How to copy values of only a subset of object properties to another existing object in TypeScript

My suggestion for copyPropertyvalues() would be something like this:

function copyPropertyvalues<T, K extends keyof T>(s: Pick<T, K>, d: T, ks: K[]) {
ks.forEach(k => d[k] = s[k]);
return d;
}

The function is generic in the type T of the destination object, and the type K of the key names you're going to copy from the source to the destination object. I assume that you want to require that the properties you're copying from the source should be the same type as the properties already in the destination; for example, you wouldn't copy the "a" property from a source of type {a: number} to a destination of type {a: string}, since you'd be writing a number to a string and violating the type of the destination.

Note that we don't need the source object to be exactly T; it only has to agree with T at all the keys in K. That is, we only say that it must be Pick<T, K> using the Pick<T, K> utility type.

And note that we are definitely passing in an array of key strings, which the compiler will infer not just as string, but specifically as a union of string literal types which are a subset of keyof T (using the keyof type operator to get a union of the known keys of T). So if you pass in ["b", "d"], the compiler will infer that as being of type Array<"b" | "d"> and not just Array<string>. This will give you the type safety you're looking for, without trying to worry about something like nameof which does not exist in JavaScript (and will not exist in TypeScript until it does, see microsoft/TypeScript#1579).


Okay, let's try it out:

copyPropertyvalues(
obj2, // source
obj1, // destination
["b", "d"] // properties to copy
);
console.log(obj1)
/* {
"a": "A",
"b": "B2",
"c": "C",
"d": "D2"
} */

Looks like it behaves how you want. And if you put the wrong keys in there you get compile time errors:

copyPropertyvalues(
obj2, // error!
obj1,
["a"]
)

copyPropertyvalues(
obj2,// error!
obj1,
["z"]
)

Playground link to code

How to get a subset of a javascript object's properties

Using Object Destructuring and Property Shorthand

const object = { a: 5, b: 6, c: 7  };

const picked = (({ a, c }) => ({ a, c }))(object);

console.log(picked); // { a: 5, c: 7 }


Related Topics



Leave a reply



Submit