0

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?

1
  • is it an assigned home work to use reduce? Because I feel a simple loop is good here. or you can use options.findIndex(x=>x.selected) Commented Feb 10, 2019 at 4:36

5 Answers 5

1

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);

Sign up to request clarification or add additional context in comments.

1 Comment

From how I understand his question that's his current output and the expected output should be the same if he would use map + filter.
1

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>

Comments

0

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)

Comments

0

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); 

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.