To be clear, given an Array of Objects, likely with homogenous keys:
const data = [
{ name: "tomato", isHealthy: true, "calories": 300 },
{ name: "french fries", isHealthy: false, "calories": 1000 },
{ name: "lettuce", isHealthy: true, "calories": 100 },
{ name: "nacho cheese", isHealthy: false, "calories": 1200 },
{ name: "boring chicken", isHealthy: true, "calories": 500 },
];
and a few filters say:
const isHealthy = function(items) {
return items.filter(i => i.isHealthy);
};
const caloriesAbove = function(items, calories) {
return items.filter(i => i.calories > calories);
};
I'd like to be able to call the filter chain like:
wrapper(data).isHealthy().caloriesAbove(500).value.map(...)
It is a bit difficult to see how lodash accomplishes this. Further, is there a way to do this w/o having to explicitly unwrap in order to get the value? This is not a requirement as I think this might have to use undesirable hacks.
This is how lodash does it:
function wrapper(items) {
return {
value: items,
isHealthy() {
return wrapper(items.filter(it => it.isHealthy));
},
caloriesAbove(calories) {
return wrapper(items.filter(it => it.calories > calories));
},
};
}
Further, is there a way to do this w/o having to explicitly unwrap in order to get the value?
Since ES6 you can extend arrays:
class Items extends Array {
isHealthy() {
return this.filter(it => it.isHealthy);
}
}
To turn an existing array into Items, just do Items.from(array)
or new Items(...array)
then you can:
items
.filter(it => it.calories > 2) // native methods can be used, they return Item instances, not Arrays
.isHealthy() // our custom methods also work
.map(it => it.name)[0] //its a regular array with indices.