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

Duoro
  • 288
  • 1
  • 3
  • 14

3 Answers3

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
Sheraff
  • 5,730
  • 3
  • 28
  • 53
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.

ConductedClever
  • 4,175
  • 2
  • 35
  • 69
  • 1
    Thank you. I think your code made it much simpler for me to understand. I didn't think about using acc like that. – Duoro Apr 23 '21 at 07:36
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);
Bhuwan
  • 16,525
  • 5
  • 34
  • 57