-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimplement-classnames.js
More file actions
52 lines (42 loc) · 1.31 KB
/
Copy pathimplement-classnames.js
File metadata and controls
52 lines (42 loc) · 1.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
* * Implement classNames
*
* classNames() accepts arbitrary arguments, filter out the falsy values, and generate the final className string.
*
* @param {...any} args
* @returns {string}
*/
// O(n) time | O(n) space
function classNames(...args) {
let result = ''
for (let item of args) {
// Check for falsy values
if (
item === null ||
item === undefined ||
item === false ||
typeof item === 'symbol'
)
continue
// Check for string or number
if (typeof item === 'string' || typeof item === 'number') {
result += item + ' '
// Check for array
} else if (Array.isArray(item)) {
item.flat(Infinity).forEach((i) => args.push(i)) // flatten the array and push each item to args
// Check for object
} else if (typeof item === 'object') {
Object.keys(item).forEach((key) => {
if (item[key]) result += key + ' '
})
}
}
return result.trim()
}
// ------------------------------
// TESTS
console.log(classNames('foo', 'bar', 100)) // 'foo bar 100'
// Other primitives are ignored
console.log(classNames(null, undefined, Symbol(), 1n, true, false)) // ''
// Object's enumerable property keys are kept if the key is string and value is truthy
console.log(classNames({ foo: true, bar: false, duck: true })) // 'foo duck'