Skip to content
Advertisement

Javascript object generator

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

Advertisement

Answer

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)))
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement