skip to Main Content

I have three generators function the third one is delegate function

function* genNumbers() {
    yield* [1, 2, 2, 2, 3, 4, 5];
  }

  function* genLetters() {
    yield* ["A", "B", "B", "B", "C", "D"];
  }

  function* genAll() {
    yield* genNumbers();
    yield* genLetters();
  }

  let generator = genAll();

I want to print the all values by using the generator.next() But **Remove **the duplicate value, like that:

  console.log(generator.next()); // {value: 1, done: false}
  console.log(generator.next()); // {value: 2, done: false}
  console.log(generator.next()); // {value: 3, done: false}
  console.log(generator.next()); // {value: 4, done: false}
  console.log(generator.next()); // {value: 5, done: false}
  console.log(generator.next()); // {value: "A", done: false}
  console.log(generator.next()); // {value: "B", done: false}
  console.log(generator.next()); // {value: "C", done: false}
  console.log(generator.next()); // {value: "D", done: false}

3

Answers


  1. function* genNumbers() {
      yield* [1, 2, 2, 2, 3, 4, 5];
    }
    
    function* genLetters() {
      yield* ["A", "B", "B", "B", "C", "D"];
    }
    
    function* genAll() {
      const uniqueValues = new Set();
      
      for (const value of genNumbers()) {
        if (!uniqueValues.has(value)) {
          uniqueValues.add(value);
          yield value;
        }
      }
    
      for (const value of genLetters()) {
        if (!uniqueValues.has(value)) {
          uniqueValues.add(value);
          yield value;
        }
      }
    }
    
    let generator = genAll();
    
    console.log(generator.next()); // {value: 1, done: false}
    console.log(generator.next()); // {value: 2, done: false}
    console.log(generator.next()); // {value: 3, done: false}
    console.log(generator.next()); // {value: 4, done: false}
    console.log(generator.next()); // {value: 5, done: false}
    console.log(generator.next()); // {value: "A", done: false}
    console.log(generator.next()); // {value: "B", done: false}
    console.log(generator.next()); // {value: "C", done: false}
    console.log(generator.next()); // {value: "D", done: false}
    

    To achieve printing unique values without duplicates from the generators, you can modify the genAll function to use a Set to keep track of values that have already been yielded. Here’s an updated version of your code:

    Login or Signup to reply.
  2. Keeping things generator based, you could just create a generator that takes your returned generator that does the de-duping. Doing this you could then keep this as a util you can use in other places.

    Generators that take generators as source is a very memory efficient way of processing huge amounts of data, as it avoid intermediate memory storage.

    function* genNumbers() {
      yield* [1, 2, 2, 2, 3, 4, 5];
    }
    
    function* genLetters() {
      yield* ["A", "B", "B", "B", "C", "D"];
    }
    
    function* dedupe(gen) {
      const done = new Set();
      for (const v of gen) {
        if (done.has(v)) continue;
        yield v;
        done.add(v);
      }
    }
    
    function* genAll() {
      yield* genNumbers(); 
      yield* genLetters();
    }
    
    for (const g of dedupe(genAll())) console.log(g);
    Login or Signup to reply.
  3. You need two common iterator idioms: chain that combines multiple iterators sequentially and uniq which returns only unique values from an iterator:

    function* genNumbers() {
        yield* [1, 'A', 2, 2, 3, 4, 5];
    }
    
    function* genLetters() {
        yield* ["A", "B", "B", "B", "C", "D"];
    }
    
    function* chain(...iters) {
        for (let it of iters)
            yield *it
    }
    
    function* uniq(it) {
        const done = new Set();
    
        for (let x of it) {
            if (!done.has(x)) {
                yield x;
                done.add(x);
            }
        }
    }
    
    
    unqiues = uniq(chain(genNumbers(), genLetters()))
    console.log(...unqiues);

    This assumes you want to uniquify both iterators as a whole, if you want each to be handled separately, it should be the other way around:

     chain(uniq(first), uniq(second))
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search