3

So I want to use Array.prototype.reduce function to reduce some array (converted from object).

This is the object which I'll later use Object.entries to get the array.

const activityLoading = {
  topicsForClassCourse: true,
  b: false,
  c: false,
  d: true,
  e: false
}

I also have an array of keys that I want to ignore while reducing this object. So any key that are in activityLoading as well as local it will be neglected.

const local = [ "topicsForClassCourse", "e" ]

Now I want to reduce the object into a single value. If any key is true except the one in the local array, it should return true, else false.

This is what I could come up with. But it's returning false.

const loadingSome = () => {
      const local = [ "topicsForClassCourse", "timetableForClass" ];
      const entries = Object.entries(activityLoading)
      
      const reducer = (acc, current) => {
        if(local.includes(current[0])) {
          return false
        }
        if(current[1]) {
          return true;
        }
        return false
      }
      
      const result = entries.reduce(reducer, false)
      console.log(result)
    }

https://jsbin.com/nolobupeva/edit?js,console

2
  • reduce is not the right function when the target is boolean, use some or every Commented Apr 23, 2021 at 9:24
  • Maybe you are right... Using some will make much more sense. Commented Apr 23, 2021 at 11:39

3 Answers 3

2

Basically, I'd start w/ writing the test for a single value itself

function test(key, value) {
  const ignore = local.includes(key)
  return !ignore && value
}

Once you have that, there are many ways to run it on your entire object. And I'm not sure .reduce is the best way to go for this. I'd suggest going for .find

const activityLoading = {
  topicsForClassCourse: true,
  b: false,
  c: false,
  d: true,
  e: false
}
const local = [ "topicsForClassCourse", "e" ]

const result = Object.entries(activityLoading).find(([key, value]) => {
  const ignore = local.includes(key)
  return !ignore && value
})
console.log(result) // ['d', true]

const foundSomething = !!result
console.log(foundSomething) // true

And if you find it cumbersome to deal with ['d', true] being returned, using .some instead of .find will return a boolean instead of the value that matched the test.

But if you really want to, .reduce could do the job too, just be careful with 2 things:

  • how you initialize it (second argument). It should start at false because initially you assume no value matches.
  • and how you accumulate (return). It should be return accumulator || current so that any true current will make the whole result true.

const activityLoading = {
  topicsForClassCourse: true,
  b: false,
  c: false,
  d: true,
  e: false
}
const local = [ "topicsForClassCourse", "e" ]

const result = Object.entries(activityLoading).reduce((accu, [key, value]) => {
  const ignore = local.includes(key)
  const test = !ignore && value
  return accu || test
}, false)

console.log(result) // true

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

Comments

1

You should try some more simple jobs using reduce function to take it in hand. Now for your issue you can try this one:

    const loadingSome = () => {
      const local = [ "topicsForClassCourse", "timetableForClass" ];
      const entries = Object.entries(activityLoading)
      
      const reducer = (acc, current) => {
        if(local.includes(current[0])) {
          return acc
        }
        return current[1] || acc;
      }
      
      const result = entries.reduce(reducer, false)
      console.log(result)
    }

As you see you forgot to take the acc into account. I have not try out the above code but it should work. If didn't let me know.

1 Comment

Thank you. I think your code made it much simpler for me to understand. I didn't think about using acc like that.
1

How about first filter the object to filter out the local array keys using filter and then use some to check any key is true/false.

const activityLoading = {
  topicsForClassCourse: true,
  b: false,
  c: false,
  d: true,
  e: false
};
const local = ["topicsForClassCourse", "e"];
let result = Object.entries(activityLoading)
  .filter(([key, value]) => !local.includes(key))
  .some(([key, value]) => value);
console.log(result);

or you can use only some array helper

const activityLoading = {
  topicsForClassCourse: true,
  b: false,
  c: false,
  d: true,
  e: false
};
const local = ["topicsForClassCourse", "e"];
let result = Object.entries(activityLoading)
  .some(([key, value]) => !local.includes(key) && value)
console.log(result);

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.