fscore
fscore

Reputation: 2619

How to convert this array of objects to use reduce javascript

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

Answers (5)

Ehsan
Ehsan

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

Fullstack Guy
Fullstack Guy

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

charlietfl
charlietfl

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

adiga
adiga

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

cyr_x
cyr_x

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

Related Questions