Package Exports
- floppy-filter
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (floppy-filter) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Floppy Filter
Just another library to filter JavaScript objects, based on a simple and flexible pattern with support for negation.
Installation
npm install floppy-filter --saveFeatures
- Wildcard Matching:
*can be used with.to select different paths within an object. - Negation:
!can be used with*to allow all properties except negated paths within an object. - Explicit: Selecting
user.addressdoes not show address object and its nested properties butuser.address.citywill selectaddressobject withcityproperty, oruser.address.*to selectaddressobject and all its primitive properties
Primitive Properties: Properties with values that are not Objects
Usage
We will use this sample object to apply library functionalities
const user = {
"_id": "5f13c2e046d4e1b898cd25c5",
"index": 0,
"guid": "674cd798-87a8-44e7-9be1-d4ad9c50a923",
"isActive": true,
"balance": "$3,848.78",
"picture": "http://placehold.it/32x32",
"age": 35,
"eyeColor": "blue",
"name": {
"first": "Callahan",
"last": "Gilliam"
},
"address": {
"country": "Philippines",
"city": "Baliuag Nuevo",
"street": "82 Roxbury Drive",
"location": {
"lat": 13.5201065,
"lng": 123.1985807
}
},
"company": "OLYMPIX",
"email": "callahan.gilliam@olympix.info",
"phone": "+1 (845) 441-3694",
"about": "Ullamco irure est dolor non culpa consequat.",
"registered": "Sunday, March 15, 2015 2:07 AM",
"latitude": "-14.770193",
"longitude": "54.884539",
"tags": ["ullamco", "amet", "enim", "id", "fugiat"],
"range": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
"friends": [
{
"id": 0,
"name": "Corine Mcleod"
},
{
"id": 1,
"name": "Lauri Fields"
},
{
"id": 2,
"name": "Jami Cortez"
}
],
"greeting": "Hello, Callahan! You have 8 unread messages.",
"favoriteFruit": "apple"
}Select Subset
Select one or more properties
filterObject(user, ['_id', 'guid']);
// Output
{
"_id": "5f13c2e046d4e1b898cd25c5",
"guid": "674cd798-87a8-44e7-9be1-d4ad9c50a923"
}Select from nested properties
filterObject(user, ['_id', 'guid', 'address.city']);
// Output
{
"_id": "5f13c2e046d4e1b898cd25c5",
"guid": "674cd798-87a8-44e7-9be1-d4ad9c50a923",
"address": {
"city": "Baliuag Nuevo"
}
}We can select all nested properties using
*operator, But this will only select first level ofaddressobject which contains only (country,city,street) properties, but not thelocationattribute as its an object not primitive.
Here is an example:
filterObject(user, ['_id', 'guid', 'address.*']);
// Output
{
"_id": "5f13c2e046d4e1b898cd25c5",
"guid": "674cd798-87a8-44e7-9be1-d4ad9c50a923",
"address": {
"country": "Philippines",
"city": "Baliuag Nuevo",
"street": "82 Roxbury Drive"
}
}To select all nested properties (including objects) in address object, We need to use ** which will select all nested paths inside object
filterObject(user, ['_id', 'guid', 'address.**']);
// Output
{
"_id": "5f13c2e046d4e1b898cd25c5",
"guid": "674cd798-87a8-44e7-9be1-d4ad9c50a923",
"address": {
"country": "Philippines",
"city": "Baliuag Nuevo",
"street": "82 Roxbury Drive",
"location": {
"lat": 13.5201065,
"lng": 123.1985807
}
}
}Select Subset from an Array
We can select at a specific index of an array using
array.i.attrSelect specific properties within specific item, Exuser.friends.0.idarray.i.*Select whole item primitive properties (Without Objects) , Exuser.friends.0.*array.i.**Select whole item wit all nested properties, Exuser.friends.0.**
Using
array.0will not return the item at index0You must explicitly select specific attribute likefriends.0.id, select all using*likefriends.0.*orfriends.0.**
filterObject(user, ['_id', 'guid', 'friends.0.id']);
// Output
{
"_id": "5f13c2e046d4e1b898cd25c5",
"guid": "674cd798-87a8-44e7-9be1-d4ad9c50a923",
"friends": [
{
"id": 0
}
]
}
filterObject(user, ['_id', 'guid', 'friends.0.*']);
// Output
{
"_id": "5f13c2e046d4e1b898cd25c5",
"guid": "674cd798-87a8-44e7-9be1-d4ad9c50a923",
"friends": [
{
"id": 0,
"name": "Corine Mcleod"
}
]
}Negation
Select all properties, without _id and guid properties
filterObject(user, ['*', '!_id', '!guid']);
// Output
{
"index": 0,
"isActive": true,
"balance": "$3,848.78",
"picture": "http://placehold.it/32x32",
...
}Select all properties, without address.country property
filterObject(user, ['*', '!address.country']);
// Output
{
...,
"address": {
"city": "Baliuag Nuevo",
"street": "82 Roxbury Drive",
"location": {
"lat": 13.5201065,
"lng": 123.1985807
}
},
...
}Filter object with negation like
['*', '!address']to filter outaddressobject will not work, you should explicitly specify insideaddressobject, like using:
['*', '!address.country']to filter outcountryproperty['*', '!address.*']to filter out all primitive properties (country,city,street)['*', '!address.**']to filter out the wholeaddressobject
Select all properties, but filter out id property from first object inside friends array
filterObject(user, ['*', '!friends.0.id']);
// Output
{
...,
"friends": [
{
"name": "Corine Mcleod"
},
{
"id": 1,
"name": "Lauri Fields"
},
{
"id": 2,
"name": "Jami Cortez"
}
],
...
}Select all properties, but filter out id property from all nested objects inside friends array
filterObject(user, ['*', '!friends.*.id']);
// Output
{
...,
"friends": [
{
"name": "Corine Mcleod"
},
{
"name": "Lauri Fields"
},
{
"name": "Jami Cortez"
}
],
...
}Select all properties, but filter out first object inside friends array
filterObject(user, ['*', '!friends.0.*']);
// Output
{
...,
"friends": [
{
"id": 1,
"name": "Lauri Fields"
},
{
"id": 2,
"name": "Jami Cortez"
}
],
...
}Interesting use cases
Combining *, selection patterns and negation patterns makes it very flexible to filter JavaScript objects
You can select all primitive properties using these filters ['*', '!**.**']
const user = {
"name": "John",
"age": 24,
"address": {
"country": "Indonesia",
"city": "Gombong",
"street": "81 Upham Lane",
"location": {
"lat": -7.6052823,
"lng": 109.5151561
}
},
"phones": ["+1 (881) 402-2942", "+1 (881) 402-2946"]
};
const filter = ['*', '!**.**'];
const result = filterObject(user, filter);
console.log(result);The result:
{
"name": "John",
"age": 24
}Or do the opposite and select only objects and ignore primitive properties using these filters ['*', '!*']
and the result will be:
{
"address": {
"country": "Indonesia",
"city": "Gombong",
"street": "81 Upham Lane",
"location": {
"lat": -7.6052823,
"lng": 109.5151561
}
},
"phones": ["+1 (881) 402-2942", "+1 (881) 402-2946"]
}Patterns
| Pattern (Sample) | Description |
|---|---|
* |
Select all properties in object, including all nested object, arrays (All depth levels, clone original object) |
user.* |
Inside user object, select all primitive properties (No Objects) |
user.*.name |
Inside user object, select "name" property within nested objects (first depth level) |
user.** |
Inside user object, select all nested objects and arrays (All depth levels) |
user.**.name |
Inside user object, select all objects with "name" property (All depth levels) |
*.name |
Select all objects with "name" property (first depth level) within root object |
**.name |
Select all objects with "name" property in all nested objects (All depth levels) within root object |
All previous patterns can be used with negation operator
!
License MIT