JavaScript Elegant reduce function

Another approach, which might or might not help with your fundamental requirements, is to convert this to a more useful format:

const roomSettings = settings => {
  const globals = settings.filter(s => s.room == null)
    .reduce((all, {key, value}) => ({...all, [key]: value}), {})
  
  return settings.filter(s => s.room != null)
    .reduce((all, {room, key, value}) => ({
      ...all, 
      [room]: {...(all[room] || globals), [key]: value}
    }), {} )
}

const settings = [{"key": "radioEnabled", "room": null, "value": true}, {"key": "radioEnabled", "room": 24, "value": false}, {"key": "name", "room": 24, "value": "Jack"}, {"key": "name", "room": 23, "value": "Mike"}, {"key": "radioEnabled", "room": 23, "value": false}, {"key": "tvEnabled", "room": null, "value": false}, {"key": "name", "room": 25, "value": "Beth"}]

console.log(roomSettings(settings))
Answer:1

Here's a possible alternative -

const globals =
  { radioEnabled: true
  , tvEnabled: false
  }

const settings =
  [ { room: 24, name: 'Jack' }
  , { room: 24, radioEnabled: false }
  , { room: 25, name: 'Mike' }
  , { room: 25, tvEnabled: true }
  ]

const assign = (o1, o2) =>
  ({ ...o1, ...o2 })

const getConfig = (room, settings = []) =>
  settings
    .filter (s => s.room === room)
    .reduce (assign, globals)

console .log
  ( getConfig (24, settings)
    // { radioEnabled: false
    // , tvEnabled: false
    // , room: 24
    // , name: 'Jack'
    // }

  , getConfig (25, settings)
    // { radioEnabled: true
    // , tvEnabled: true
    // , room: 25
    // , name: 'Mike'
    // }
  )
Answer:2

I would suggest:

  • Filter first for where room is null
  • Then filter for where room is the desired room number
  • Concatenate both results in that order
  • Add that to a Map to get only one entry per key
  • Output as an array

The fact that the first two filter-results are concatenated in that order will ensure that null room entries get lower priority than non-null entries.

function getAll(room){
    return [...new Map([...settings.filter(a => a.room === null), 
                        ...settings.filter(a => a.room === room)]
               .map(a => [a.key, a])).values()]
}

const settings = [{room: null, key: 'radioEnabled', value: true},{room: 24,   key: 'radioEnabled', value: false},{room: 24,   key: 'name', value: 'Jack'},{room: 23,   key: 'name',         value: 'Mike'},{room: 23,   key: 'radioEnabled', value: false},{room: null, key: 'tvEnabled', value: false}];

console.log(getAll(24));
Answer:3

How can i display all failures when running tests. test('test case', async (t) => ){ await t.expect(1).eql(2); await t.expect(3).eql(4); } What i get (first failure, then stops): 1) ...

How can i display all failures when running tests. test('test case', async (t) => ){ await t.expect(1).eql(2); await t.expect(3).eql(4); } What i get (first failure, then stops): 1) ...

I've created this function, however when it runs on the website it's designed for it is returning undefined. I did some quick Googling and found that because it's an asynchronous function, it ...

I've created this function, however when it runs on the website it's designed for it is returning undefined. I did some quick Googling and found that because it's an asynchronous function, it ...

I cannot centralize v-radio-group. Here's what I got: <v-container grid-list-md text-xs-center> <v-form ref="form> <div v-if="question.question_type == 'YESNO' "> &...

I cannot centralize v-radio-group. Here's what I got: <v-container grid-list-md text-xs-center> <v-form ref="form> <div v-if="question.question_type == 'YESNO' "> &...

I am looping over file directories and for each location I am reading the files in this directory with an async fs.readFile(). How can I best determine if all the async readFile() calls have completed?...

I am looping over file directories and for each location I am reading the files in this directory with an async fs.readFile(). How can I best determine if all the async readFile() calls have completed?...