Reputation: 2619
I'm trying to convert this function to use reduce. I am halfway through. When the selected value is true
I want to know the index of that element.
let options = [
{label: 'foo1', selected: false},
{label: 'foo2', selected: true},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
];
const obj = options
.map((option, index) => (option.selected ? index : -1))
.filter((val) => val !== -1)[0];
Result: 1
My attempt is this:
const obj = options.reduce((acc, currentValue, index) => {
const i = currentValue["selected"] ? index : -1;
return acc.concat(i)
}, []); // [-1,1,-1,-1,-1]
How do I change the entire thing to use reduce?
Upvotes: 0
Views: 223
Reputation: 12951
Another way is use of push
instead of concat
:
let options = [
{label: 'foo1', selected: false},
{label: 'foo2', selected: true},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
];
var obj = options.reduce( (acc, currentValue, index) => {
currentValue.selected ? acc.push(index) : ''; return acc} ,[] ) ;
console.log(obj)
Upvotes: 0
Reputation: 16908
Using Array#reduce
and the ...
spread operator keep the existing indexes and add the new index if selected
is true
.
let options = [
{label: 'foo1', selected: false},
{label: 'foo2', selected: true},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
{label: 'foo2', selected: true},
{label: 'foo2', selected: 1}
];
const obj = options.reduce((acc, currentValue, index) => {
// checking only for boolean true not for truthy values
return acc = currentValue["selected"] === true ? [...acc, index] : acc;
}, []);
console.log(obj);
Upvotes: 0
Reputation: 171679
Use a ternary in concat()
to set the value to be inserted. Array#concat()
returns the updated array so that is the return for reduce()
.
Or use spread to return new array [...accumulator, selsected ? i :-1]
const res = options.reduce((a, {selected:s}, i) => a.concat(s ? i : -1) , []);
// OR
// const res = options.reduce((a, {selected:s}, i) => [....a,s ? i : -1] , []);
console.log(res)
<script>
let options = [
{label: 'foo1', selected: false},
{label: 'foo2', selected: true},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
];
</script>
Upvotes: 1
Reputation: 35212
If you want indexes with selected
= true, then you could do something like this using reduce
. If the current item in context has selected
=== true, add the index to the accumulator, else return the accumulator. Currently, you're adding -1
if the condition is false
let options = [
{label: 'foo1', selected: false},
{label: 'foo2', selected: true},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
];
const selectedIndexes = options.reduce((r, o, i) => o.selected ? r.concat(i) : r, [])
console.log(selectedIndexes)
If you want the whole object, then you can simply use filter
:
let options = [{label:'foo1',selected:false},{label:'foo2',selected:true},{label:'foo2',selected:false},{label:'foo2',selected:false},{label:'foo2',selected:false},];
const filtered = options.filter(o => o.selected)
console.log(filtered)
Upvotes: 0
Reputation: 14257
Add the index to the result only if option.selected
is true otherwise do nothing.
let options = [
{label: 'foo1', selected: false},
{label: 'foo2', selected: true},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
{label: 'foo2', selected: false},
];
const selected = options.reduce((arr, option, index) => {
return option.selected ? arr.concat(index) : arr;
}, []);
console.log(selected);
Upvotes: 1