Skip to content

Instantly share code, notes, and snippets.

@chrislaughlin
Created February 3, 2022 20:34

Revisions

  1. chrislaughlin created this gist Feb 3, 2022.
    82 changes: 82 additions & 0 deletions pattern-matching.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    import flatten from 'flat';
    import objPath from 'object-path';


    const _matchKeys = (matchOn, matchWith) => {
    const matchWithPaths = Object.keys(flatten(matchWith));
    const matchWithValues = matchWithPaths.map(path => {
    return objPath.get(matchWith, path);
    })
    const matchOnValues = matchWithPaths.map(path => {
    return objPath.get(matchOn, path);
    })

    return matchOnValues.every((value, index) => {
    return value === matchWithValues[index];
    })
    }


    const _with = matchOn => (matchWith, onMatch) => {
    const jsonMatchOn = JSON.stringify(matchOn);
    const jsonMatchWith = JSON.stringify(matchWith);
    // If the whole object matches
    if (jsonMatchOn === jsonMatchWith) {
    return onMatch();
    }

    if (_matchKeys(matchOn, matchWith)) {
    return onMatch();
    }

    }


    const match = (matchOn) => {
    return {
    with: _with(matchOn)
    }
    }

    //Main useage
    const myObj = {
    name: 'chris'
    };

    match(myObj)
    .with({name: 'chris'}, () => console.log('matched with Chris'));
    //matched with Chris

    match(myObj)
    .with({name: 'john'}, () => console.log('matched with John'));
    //no match

    const myObj1 = {
    status: '200',
    response: {
    data: 'hello drunk world',
    headers: [
    'Content-Type: text/plain'
    ],
    forward: false,
    foo: {
    bar: {
    baz: 'hello'
    }
    }
    }
    }

    match(myObj1).with(
    {
    response: {
    foo: {
    bar: {
    baz: 'hello'
    }
    }
    }
    },
    () => console.log('matched'),
    );
    //matched