Source

Adrian Neumann, Simple Programming Problems, Lists, Strings problem 1: “Write a function that returns the largest element in a list.”

Description

Define a generic function that, given an array, returns the largest element it contains.

Treat numeric values literally: 99 is the largest element in the array [0, 1, 99]. Measure the size of an associative array (hash map) by the number of keys it contains. If two or more elements are the largest, return the first largest element. If passed data that is not an array, or if the array is empty, return null.

1
2
3
4
5
6
7
8
9
10
11
0 ⟹ null

[] ⟹ null

[null, undefined, 1] ⟹ 1

[0, 999, 23] ⟹ 999

['foo', 'bar'] ⟹ 'foo'

[null, undefined, 'foobar', 5, [1, 2, 3], {a: 1, b: 2}] ⟹ 'foobar'

My solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const getSize = x =>
    !x // Handle null and undefined.
        ? 0
        : typeof x === 'number' 
            ? x
            : typeof x === 'object'
                ? Object.keys(x).length
                : x.length; // Handle everything else.


const largest = arr =>
    !arr || !arr.length
        ? null
        : arr.reduce((a, b) => getSize(a) >= getSize(b) ? a : b);


module.exports = {getSize, largest};

Tests

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
const assert = require('assert')
    , getSize = require('./largest.js').getSize
    , largest = require('./largest.js').largest;


// getSize()
// ---------
describe('#getSize()', () => {
    it('Should return 0 for null and undefined', () => {
        assert.strictEqual(getSize(null), 0);
        assert.strictEqual(getSize(undefined), 0);
    });
    it('Should return the same value if given a numeric value', () => {
        assert.strictEqual(getSize(3), 3);
    });
    it('Should return the value of the length property of a string', () => {
        assert.strictEqual(getSize('foo'), 3);
    });
    it('Should return the value of the length property of an array', () => {
        assert.strictEqual(getSize([1, 2, 3]), 3);
    });
    it('Should measure the size of an object by the number of keys ' +
       'it contains', () => {
        assert.strictEqual(getSize({a:1, b:2}), 2);
    });
});


// largest()
// ---------
describe('#largest()', () => {

    describe('boundaries', () => {
        it('Should return null if passed anything but an array', () => {
            assert.strictEqual(largest(null), null);
        });
        it('Should return null if array is empty', () => {
            assert.strictEqual(largest([]), null);
        });
        it('Should treat elements without a length as having length 0', () => {
            assert.strictEqual(largest([null, undefined, 1]), 1);
        });
    });

    describe('expected values', () => {
        it('Should return the largest number in a list of numbers', () => {
            assert.strictEqual(largest([0, 999, 23]), 999);
        });
        it('Should return the longest string in a list of strings', () => {
            const a = 'foo', b = 'barbaz', c = 'qux';
            assert.strictEqual(largest([a, b, c]), b);
        });
        it('Should return the longest list in a list of lists', () => {
            const a = [0]
                , b = [1, 2, 3]
                , c = [4, 5];
            assert.deepStrictEqual(largest([a, b, c]), b);
        });
        it('Should return the largest object in a list of objects', () => {
            const a = {x: 0}
                , b = {x: 0, y: 1, z: 2}
                , c = {x: 0, y: 1};
            assert.deepStrictEqual(largest([a, b, c]), b);
        });
    });

    describe('expected behavior', () => {
        it('Should return the first of two or more equal largest elements', () => {
            const a = [0]
                , b = [1, 2]
                , c = [4, 5];
            assert.deepStrictEqual(largest([a, b, c]), b);
        });
        it('Should correctly handle arrays of mixed data types', () => {
            let a = null
            , b = undefined
            , c = 5
            , d = 'foo'
            , e = [1, 2, 3, 4]
            , f = {a: 1, b: 2};
            assert.strictEqual(largest([a, b, c, d, e, f]), c);

            e = [1, 2, 3, 4, 5, 6];
            assert.strictEqual(largest([a, b, c, d, e, f]), e);

            d = 'foobarbaz';
            assert.strictEqual(largest([a, b, c, d, e, f]), d);        
        });
    });

});