1

I have an object and I want to fill an array with the object property and repeat each property a number of times, based on its value. An example:

obj = {
   watches: 3
   rings: 1
}
// => ['watches', 'watches', 'watches', 'rings']

Below is what I have so far. I'm having a hard time figuring how to repeat each property based on the associated value?

function arrayBuilder(obj) {
  let objToArr = [];

  for (let [property, value] of Object.entries(obj)) {
    objToArr.push(property);
  }
  return objToArr;
}

console.log(arrayBuilder({watches: 3, rings: 1}));
// => [ 'watches', 'rings' ]
Jonathan Wilson
  • 4,138
  • 1
  • 24
  • 36
Ralitza
  • 741
  • 2
  • 7
  • 12

6 Answers6

2

You were just missing an inner loop:

function arrayBuilder(obj) {
  let objToArr = [];

  for (let [property, value] of Object.entries(obj)) {
    for(var i=0; i<value; i++){
      objToArr.push(property);
    }
  }
  return objToArr;
}

console.log(arrayBuilder({watches: 3, rings: 1}));
Jonathan Wilson
  • 4,138
  • 1
  • 24
  • 36
2

You can use Array.flatMap() (note the support) with Array.fill():

const obj = {
   watches: 3,
   rings: 1
}

const result = Object.entries(obj).flatMap(([k, v]) => Array(v).fill(k));

console.log(result);

Or Array.reduce() with array spread, if flatMap is not supported:

const obj = {
   watches: 3,
   rings: 1
}

const result = Object.entries(obj)
  .reduce((r, [k, v]) => [...r, ...Array(v).fill(k)], []); // or r.concat(Array(v).fill(k)) instead of the spread

console.log(result);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
1

Just add another loop:

 for (let [property, value] of Object.entries(obj)) {
   for(let i = 0; i < value; i++) {
     objToArr.push(property);
   }
 }
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
1

To achieve expected result, use below option using repeat and split methods

var obj = {
   watches: 3,
   rings: 1
}
let result = []
for(key in obj){
  result.push(...key.concat(" ").repeat(obj[key]).trim().split(" "))
}

console.log(result)

codepen - https://codepen.io/nagasai/pen/ZVzoGB?editors=0010

Naga Sai A
  • 10,771
  • 1
  • 21
  • 40
1

Go through the keys, for each key, create an array of the required length, fill the resulting array with the names of the key, and combine the resulting arrays:

function arrayBuilder(obj) {
  return [].concat.apply(
    [],
    Object
      .entries(obj)
      .map(([key, value]) => new Array(value).fill(key))
  )
}
console.log(arrayBuilder({watches: 3, rings: 1}))
stdob--
  • 28,222
  • 5
  • 58
  • 73
1

You can do this via Array.reduce and Object.keys:

const obj = { watches: 3, rings: 1 }

const result = Object.keys(obj).reduce((acc, key) => 
   [...acc, ...new Array(obj[key]).fill(key)], [])

console.log(result)

The idea is to get the keys from the object and use them to get the length of the array needed for the Array.fill. Using Array.fill you can fill the array with the same values once you have it setup with the correct length.

Akrion
  • 18,117
  • 1
  • 34
  • 54