I am trying to use an array map to filter a object a bit further to prepare it to send to the server to for saving. I can filter to 1 key value, which is great, but I want to take it 1 step further and check them against a boolean inside.
So, right now this is what I have -
$scope.appIds = $scope.applicationsHere.map( function(obj){ if(obj.selected == true){ return obj.id; } });
This works great for pulling out the id's, however I don't want to push them in this new array if they their selected value == false, so I put a conditional to filter further. This somewhat works, I get an array of id's, but the id's that have .selected == false are still in the array, just with the value of null. So If I have 4 items in the object and 2 of them are false it looks like this -
appIds = {id1, id2, null, null};
My question is - is there a way to do this without the nulls being put in there. Thanks for reading!
To use a condition inside map() in React:Call the map() method on an array. Use a ternary operator to check if the condition is truthy. The operator returns the value to the left of the colon if the condition is truthy, otherwise the value to the right is returned.
Using JavaScript `map()` and `filter()` Together for Composition. JavaScript's Array#map() and Array#filter() functions are great when used together because they allow you to compose simple functions.
map creates a new array by transforming every element in an array individually. filter creates a new array by removing elements that don't belong. reduce , on the other hand, takes all of the elements in an array and reduces them into a single value. Just like map and filter , reduce is defined on Array.
map() can be used to iterate through objects in an array and, in a similar fashion to traditional arrays, modify the content of each individual object and return a new array.
You're looking for the .filter()
function:
$scope.appIds = $scope.applicationsHere.filter(function(obj) { return obj.selected; });
That'll produce an array that contains only those objects whose "selected" property is true
(or truthy).
edit sorry I was getting some coffee and I missed the comments - yes, as jAndy noted in a comment, to filter and then pluck out just the "id" values, it'd be:
$scope.appIds = $scope.applicationsHere.filter(function(obj) { return obj.selected; }).map(function(obj) { return obj.id; });
Some functional libraries (like Functional, which in my opinion doesn't get enough love) have a .pluck()
function to extract property values from a list of objects, but native JavaScript has a pretty lean set of such tools.
You should use Array.prototype.reduce to do this. I did do a little JS perf test to verify that this is more performant than doing a .filter
+ .map
.
$scope.appIds = $scope.applicationsHere.reduce(function(ids, obj){ if(obj.selected === true){ ids.push(obj.id); } return ids; }, []);
Just for the sake of clarity, here's the sample .reduce
I used in the JSPerf test:
var things = [ {id: 1, selected: true}, {id: 2, selected: true}, {id: 3, selected: true}, {id: 4, selected: true}, {id: 5, selected: false}, {id: 6, selected: true}, {id: 7, selected: false}, {id: 8, selected: true}, {id: 9, selected: false}, {id: 10, selected: true}, ]; var ids = things.reduce((ids, thing) => { if (thing.selected) { ids.push(thing.id); } return ids; }, []); console.log(ids)
EDIT 1
Note, As of 2/2018 Reduce + Push is fastest in Chrome and Edge, but slower than Filter + Map in Firefox
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With