DEV Community

Andrew Elans
Andrew Elans

Posted on • Edited on

Array.reduce() to fill <select>

I have a list of colors sitting in my database and a <select> HTML element where I want to use these colors as <option>s.

Colors

I get the values from the database and store them in a variable.

const colors = [ {val: "1", name: "Black"}, {val: "2", name: "Red"}, {val: "3", name: "Yellow"}, {val: "4", name: "Green"}, {val: "5", name: "Blue"}, {val: "6", name: "White"} ] 
Enter fullscreen mode Exit fullscreen mode

Generate options with Array.reduce()

With return in the reducer callback

const colorOptions = colors.reduce( (options, color) => { options.push(`<option value="${color.val}">${color.name}</option>`) return options }, [] ) 
Enter fullscreen mode Exit fullscreen mode

Without the return word in the reducer callback

We use Grouping ( ) and Comma (,) operators for one-liner implementation.
Identation is added for better human readability.

const colorOptions = colors.reduce( (options, color) => ( options.push(`<option value="${color.val}">${color.name}</option>`), options ), [] ) 
Enter fullscreen mode Exit fullscreen mode

Resulting colorOptions

[ '<option value="1">Black</option>', '<option value="2">Red</option>', '<option value="3">Yellow</option>', '<option value="4">Green</option>', '<option value="5">Blue</option>', '<option value="6">White</option>' ] 
Enter fullscreen mode Exit fullscreen mode

Sort before reducing

You can also sort on val or name before Array.reduce().

const colors = [ {val: "1", name: "Black"}, {val: "2", name: "Red"}, {val: "3", name: "Yellow"}, {val: "4", name: "Green"}, {val: "5", name: "Blue"}, {val: "6", name: "White"} ].sort( (a, b) => a.name.localeCompare(b.name) ) // colors => [ // '<option value="1">Black</option>',  // '<option value="5">Blue</option>',  // '<option value="4">Green</option>',  // '<option value="2">Red</option>',  // '<option value="6">White</option>',  // '<option value="3">Yellow</option>' // ] 
Enter fullscreen mode Exit fullscreen mode

Use DocumentFragment to fill in <select>

We have a <select> on a page which is currently empty.

<select id="colors-select"></select> 
Enter fullscreen mode Exit fullscreen mode

We can use the DocumentFragment interface to load <select> with options as nodes.

Create DocumentFragment

const fragment = document.createRange().createContextualFragment( colorOptions.join('') // convert colors array to string ) 
Enter fullscreen mode Exit fullscreen mode

Fill in <select>

document.getElementById('colors-select').appendChild(fragment) 
Enter fullscreen mode Exit fullscreen mode

Result

<select id="colors-select"> <option value="1">Black</option> <option value="5">Blue</option> <option value="4">Green</option> <option value="2">Red</option> <option value="6">White</option> <option value="3">Yellow</option> </select> 
Enter fullscreen mode Exit fullscreen mode

Full code snippet

const colors = [ {val: "1", name: "Black"}, {val: "2", name: "Red"}, {val: "3", name: "Yellow"}, {val: "4", name: "Green"}, {val: "5", name: "Blue"}, {val: "6", name: "White"} ].sort( (a, b) => a.name.localeCompare(b.name) ) const colorOptions = colors.reduce( (options, color) => ( options.push(`<option value="${color.val}">${color.name}</option>`), options ), [] ).join('') const fragment = document.createRange().createContextualFragment(colorOptions) document.getElementById('colors-select').appendChild(fragment) 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)