1

Is there a generator approach to constructing a mapping (object)? I just need key/value mapping.

For generating array, I can write something like this

function* rangeA(start, stop) {
  while(start < stop)
    yield start++
}

let data = [...rangeA(1, 3), ...rangeA(20, 22)]
// data is [1, 2, 20, 21]

Non generator approach to construct an object in a similar way can look like this

function rangeB(start, stop) {
  let result = {}
  while(start < stop) {
    result[start] = start
    start++
  }
  return result
}
let data = {...rangeB(1, 3), ...rangeB(20, 22)}
// data is {1: 1, 2: 2, 20: 20, 21: 21}

Is there a generator approach to construct an object? Something like this

// DOES NOT WORK
function* rangeC(start, stop) {
  while(start < stop) {
    yield {[start]: start}
    start++
  }
}
let data = {...rangeC(1, 3), ...rangeC(20, 22)}
// data is unfortunately an empty object

let data2 = [...rangeC(1, 3), ...rangeC(20, 22)]
// data2 is obviously [{1: 1}, {2: 2}, {3: 3}, {20: 20}, {21: 21}]
// which is not what I want.

let data3 = data2.reduce((a, b) => ({...a, ...b}))
// data3 is finally {1: 1, 2: 2, 20: 20, 21: 21}
// but it seems overcomplicated to me
3
  • 2
    Why is using a generator important? The rangeC() function could be written as a simple function. Commented Jul 7, 2022 at 12:01
  • @Pointy I'm coming from other languages where this is possible, so I need to know how to do this in JavaScript. I already know of a solution using a simple rangeB function. If that's not what you have in mind, then please just advise/direct me where to look. Maybe it's just a bad idea to use generators for this. Commented Jul 7, 2022 at 12:14
  • I don't think it's a bad idea or anything, I was just curious about the motivation or some particular problem you are trying to solve. Commented Jul 7, 2022 at 14:54

1 Answer 1

2

Try using Object.fromEntries:

function* rangeC(start, stop) {
  while(start < stop) {
    // Replace the curly brackets with square ones here
    yield [start, start]
    start++
  }
}
let data = Object.fromEntries([...rangeC(1, 3), ...rangeC(20, 22)])

For one generator, you can pass it directly:

let data = Object.fromEntries(range(1,3))

Or create a chain method to process multiple:

function* chain(...generators) {
    for (let generator of generators) {
        yield* generator;
    }
}

let data = Object.fromEntries(chain(rangeC(1,3), rangeC(10,15)))
Sign up to request clarification or add additional context in comments.

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.