Perform a union on two sets - test not passing but seems to work?

I think I have completed this correctly - but I cannot pass the tests. I’m obviously missing something but I have no idea any more what. My console.logs appear to give me the result I am seeking - that is to say I create a set containing {'a', 'b', 'c'} and then call the union method with ['c', 'd'] as the argument. The new set created returns - correctly I think - { dictionary: { a: 'a', b: 'b', c: 'c', d: 'd' }, length: 4 }.

Any ideas?

class Set {
  constructor() {
    // This will hold the set
    this.dictionary = {};
    this.length = 0;
  }
  // This method will check for the presence of an element and return true or false
  has(element) {
    return this.dictionary[element] !== undefined;
  }
  // This method will return all the values in the set
  values() {
    return Object.values(this.dictionary);
  }
  // This method will add an element to the set
  add(element) {
    if (!this.has(element)) {
      this.dictionary[element] = element;
      this.length++;
      return true;
    }

    return false;
  }
  // This method will remove an element from a set
  remove(element) {
    if (this.has(element)) {
      delete this.dictionary[element];
      this.length--;
      return true;
    }

    return false;
  }
  // This method will return the size of the set
  size() {
    return this.length;
  }
  // Only change code below this line
  union(setB) {
    console.log(setB)
    const newSet = new Set();
    console.log(newSet)
    this.values().forEach(value => newSet.add(value))
    console.log(newSet)
    if (setB.length) setB.forEach(value => newSet.add(value))
    console.log(newSet)
    return newSet
  }
  // Only change code above this line
}

And the way I have been calling it to test it works:

const obj = new Set()
obj.add('a')
obj.add('b')
obj.add('c')
obj.union(['c','d'])

Challenge: Perform a Union on Two Sets

Link to the challenge:

The forEach part of these two lines should be identical except for the set over which they are iterating.

Thanks Jeremy. I forgot to say I had already tried that. The if was just to check that there wasn’t a test condition being passed with null length.

Removing the if statement like so still doesn’t pass the test.

union(setB) {
    console.log(setB)
    const newSet = new Set();
    this.values().forEach(value => newSet.add(value))
    setB.forEach(value => newSet.add(value))
    return newSet
  }

Not the if. The first one is this.values().forEach(...) and the second is setB.forEach(...). The second one is missing something.

Thanks again Jeremy. I see what you mean, but this.values() and setB are both arrays.

To prove it, I have changed to the following:

union(setB) {
    console.log('setA', Object.values(this.dictionary))
    console.log('setB', Object.values(setB))
    const newSet = new Set();
    console.log('newSet', newSet)
    Object.values(this.dictionary).forEach(value => newSet.add(value))
    console.log(newSet)
    Object.values(setB).forEach(value => newSet.add(value))
    console.log(newSet)
    return newSet
  }
const obj = new Set()
obj.add('a')
obj.add('b')
obj.add('c')
obj.union(['c','d'])

returns

setA [ 'a', 'b', 'c' ]
setB [ 'c', 'd' ]
newSet { dictionary: {}, length: 0 }
{ dictionary: { a: 'a', b: 'b', c: 'c' }, length: 3 }
{ dictionary: { a: 'a', b: 'b', c: 'c', d: 'd' }, length: 4 }

This still does not pass, but I have no idea what is wrong.

No, it is not an array, it’s a Set(). Your original code produces the following messages when the tests run:

{ dictionary: { c: 'c', d: 'd' }, length: 2 }
{ dictionary: {}, length: 0 }
{ dictionary: { a: 'a', b: 'b', c: 'c' }, length: 3 }
{ dictionary: { a: 'a', b: 'b', c: 'c', d: 'd' }, length: 4 }

The first line the output of console.log(setB). That’s not an array, that’s a Set() object and calling its values() method will give you the array of values, as your new code shows.

You can even try an example

let setC = new Set();
setC.add(1);
setC.add(2);
setC.add(3);
setC.forEach((item) => console.log(item));

outputs TypeError: setC.forEach is not a function while setC.values().forEach((item) => console.log(item)); outputs

1
2
3

So, this line of your original code

is still not correct. Further, if you try/catch that line of code like

    try {
      if (setB.length) setB.forEach(value => newSet.add(value))
    } catch (error) {
      console.log(error);
    }

the error thrown is TypeError: setB.forEach is not a function, just like my example. So, that is the problem.

Plus, I fixed this very line the other day and that was the only change needed to pass…

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.