match-by

0.7.3 • Public • Published

Match

match-by

Build Status Coverage Status Codacy Badge Greenkeeper badge

Simple Matching for Mixed-Up Situations


This module was made with affection for but in no way trying to be a pattern matcher. We've already got that on the way. Instead, it is made to replace ugly ternary. It matches a test value to a simple key value. Simple in that the key must be a valid key in an object, so a primitive.

Motivating Examples

const traficLightDisplay = 
    intersection === 'stop'
        ? 'red'
        : intersection === 'yeild'
            ? 'yellow'
            : intersection === 'go'
                ? 'green'
                : 'yellow flashing';

becomes

const lightOptions = {
    stop: 'red',
    yeild: 'yellow',
    go: 'green',
    _: 'yellow flashing'
};
 
const traficLightDisplay = match( lightOptions, 'stop' );

Though that situation could be cleared up with a mapper function. What a mapper couldn't cleanly handle for you would be something like

const ViewType = user.developer
    ? <Debug ... />
    : user.admin
        ? user.beta
            ? <Admin beta />
            : <Admin />
        : user.beta
            ? <Customer beta />
            : <Customer />

With match it becomes

const userTypeViewMatching = match( {
    developer: () => <Debug />,
    adminBeta: () => <Admin beta />,
    admin: () => <Admin />,
    userBeta: () => <Customer beta />,
    _: () => <Customer />
} );
 
const ViewType = ( { userCase } ) =>
    userTypeViewMatching( {
        ...userCase,
        adminBeta: userCase.admin && userCase.beta,
        customerBeta: !userCase.admin && userCase.beta
    } );  

There is an additional option matchAll that will let you turn

const WeatherCard = ({ sunny, cloudy, windy, rain, snow }) => (
    <Card>
        {sunny && <SunIcon />}
        {cloudy && <CloudIcon />}
        {windy && <WindIcon />}
        {rain && <RainIcon />}
        {snow && <SnowIcon />}
    </Card>
);

into

const weatherCardMatcher = match(
    {
        sunny: SunIcon,
        cloudy: CloudIcon,
        windy: WindIcon,
        rain: RainIcon,
        snow: SnowIcon
    },
    { matchAll: true }
);
 
const WeatherCard = props => <Card>{weatherCardMatcher(props)}</Card>;

Usage

match( {
    'a': 1,
    'b': 2
}, 'a' );
// => 1

Will return undefined if no match is found

match( {
    'a': 1,
    'b': 2
}, 'c' );
// => undefined 

Will return a default value when no match is found if a default key/value is in the matchClauses

match( {
    'a': 1,
    'b': 2,
    _: 'default' // <- '_' is the default `defaultKey`
}, 'c' );
// => 'default' 

Match can be partially applied with just the matchClauses ahead of time.

const requestStatus = match( {
    200: 'success',
    404: 'JSON not found',
    _: 'Request Failed'
} );
 
const res = await fetch( jsonService )
requestStatus( res.status )

If the matching value is a function, it will be called with the testExpression

const getVectorLength = match( {
        z: ( { x, y, z } ) => Math.sqrt(** 2 + y ** 2 + z ** 2),
        y: ( { x, y } ) => Math.sqrt(** 2 + y ** 2 ),
        _: vector => vector.length
    } );
getVectorLength({x: 1, y: 2, z: 3})
// =>  3.74165
<Fetch lazy url="https://api.github.com/users/easilyBaffled">
    {  // Fetch is a render prop that passes the fetch status (`{loading, data, error}`) to its child
        match( {
            data: ( { data } ) => <pre>{JSON.stringify(data, null, 2)}</pre>
            loading: () => <h1>...Loading</h1>,
            error: ({ error }) => <h1>{error.message}</h1>
        } )
    }
</Fetch>

API

match(matchClauses, testExpression, [options={}])

source

Match a value against a set of keys and produce the associated value. The value may be a primitive, in which case it is matched directly against the keys of the matchClauses object. The value may also be an object in which case, the keys in the object, whose values are not empty are used to match against the matchClauses.

Arguments

  1. matchClauses (Object): an object whose keys will be matched against. A default value, whose key is indicated by defaultKey, can be provided in the case that there is no match
  2. testExpression (Object|boolean|number|string): a value that will be matched against the keys of matchClauses
  3. [options={}] (Object): allow the user to set the defaultKey and matchAll case;
  4. [options.defaultKey=_] (string): The key used for the default value in the matchClauses.
  5. [options.matchAll=false] (boolean): If true match will return an array of all matches otherwise it will return just the first match

Returns

(undefined|*): Returns undefined if there is no match, otherwise returns the matching value(s)

Readme

Keywords

none

Package Sidebar

Install

npm i match-by

Weekly Downloads

5

Version

0.7.3

License

MIT

Unpacked Size

19.2 kB

Total Files

4

Last publish

Collaborators

  • easilybaffled