map-fns

<h1 align="center"> <code>map-fns</code> </h1>

Usage no npm install needed!

<script type="module">
  import mapFns from 'https://cdn.skypack.dev/map-fns';
</script>

README

map-fns

Easily manipulate key-value stores in the browser and Node.js.


Why use map-fns?

  • Zero dependencies: Keep your deployments and node modules lightweight.
  • Modular: Import the functions you need, tree-shake the rest.
  • Immutable & Pure: Function arguments are not modified and new objects are returned.
  • TypeScript: Well documented and fully typed.
  • Plain JavaScript objects: Keep things simple. No custom classes.
  • Open Source: MIT licensed.
import { mergeInMap } from "map-fns";

const map = {
  alice: {
    name: "Alice",
    permissions: ["view"],
  },
  bob: {
    name: "Bob",
    permissions: ["view", "merge", "push"],
  },
};

mergeInMap(map, "alice", {
  permissions: (permissions) => [...permissions, "merge"],
});
//=> {
//     alice: {
//       name: "Alice",
//       permissions: ["view", "merge"],
//     },
//     bob: {
//       name: "Bob",
//       permissions: ["view", "merge", "push"],
//     },
//   }

map-fns supports tree-shaking. If your environment does not you can import a specific function directly.

import mergeInMap from "map-fns/mergeInMap";

Get started

You can install map-fns as an npm package:

npm i -S map-fns

Functions can be imported with import:

import { addListToMap, partialMap } from "map-fns";

You can also import a single function directly:

import mergeInMap from "map-fns/mergeInMap";

though this is unnecessary if your environment supports tree-shaking.

If you cannot use import, you can also use require.

const { mapMap } = require("map-fns");

Functions

map-fns exports a variety of functions that can be used to easily manipulate key-value stores.

Examples have yet to be created for functions that are not a link.

addListToMap

Examples of using addListToMap .

Use addListToMap to add a list of entries to a map.

import { addListToMap } from "map-fns";

const map = {
  a: { id: "a", value: 1 },
  b: { id: "b", value: 2 },
  c: { id: "c", value: 3 },
};

addListToMap(
  map,
  [
    { id: "d", value: 4 },
    { id: "e", value: 5 },
  ],
  "id"
);

//=> {
//     a: { id: "a", value: 1 },
//     b: { id: "b", value: 2 },
//     c: { id: "c", value: 3 },
//     d: { id: "d", value: 4 },
//     e: { id: "e", value: 5 },
//   }

addListToMap assumes that there is a key field (such as id in this example) whose value is equal to the entry's key in the map.

areMapsShallowEqual

Examples of using areMapsShallowEqual .

Use areMapsShallowEqual to compare two maps shallowly. For two maps to be shallowly equal, each of the following conditions must be met.

  • The maps must have the same number of keys.
  • For every key in map A, map B must contain that key.
  • For every key in the maps, comparing A[key] === B[key] must return true.
import { areMapsShallowEqual } from "map-fns";

const a1 = { a: 1, b: 2, c: 3 };
const b1 = { a: 1, b: 2, c: 3 };

areMapsShallowEqual(a1, b1);
//=> true


const a2 = { a: 1, b: 2, c: 3 };
const b2 = { a: 1, b: 2 };

areMapsShallowEqual(a2, b2);
//=> false


const a3 = { a: 1, b: 2, c: 3 };
const b3 = { a: 1, b: 2, c: 30 };

areMapsShallowEqual(a3, b3);
//=> false

Since the comparison uses ===, objects are compared by reference, not by value.

import { areMapsShallowEqual } from "map-fns";

const a1 = { a: { id: "a", value: 1 } };
const b1 = { a: { id: "a", value: 1 } };

// Since `a1.a` and `b1.a` are different object references, comparing
// them via `===` returns false.

areMapsShallowEqual(a1, b1);
//=> false


const a = { id: "a", value: 1 };
const a2 = { a };
const b2 = { a };

// Since `a2.a` and `b2.a` are the same object reference, comparing
// them via `===` returns true.

areMapsShallowEqual(a2, b2);
//=> true

mapEntries

Examples of using mapEntries .

Use mapEntries to get the list of key-value entries in a map.

import { mapEntries } from "map-fns";

const map = { a: 1, b: 2, c: 3 };

mapEntries(map);
//=> [
//     ["a", 1],
//     ["b", 2],
//     ["c", 3]
//   ]

A list of keys can be provided as the second argument to only return the entries for those keys.

import { mapEntries } from "map-fns";

const map = { a: 1, b: 2, c: 3 };

// The order of the keys determines the order of the entries

mapEntries(map, ["c", "b"]);
//=> [
//     ["c", 3]
//     ["b", 2],
//   ]

If a provided key does not exist in the map an error is thrown.

mapMap

Examples of using mapMap .

Use mapMap to transform every value in map to a new value with a callback function.

import { mapMap } from "map-fns";

const map = {
  a: 1,
  b: 2,
  c: 3,
};

mapMap(map, (n) => n * 2);
//=> {
//     a: 2,
//     b: 4,
//     c: 6,
//   }

mapPartialMap

Examples of using mapPartialMap .

Use mapPartialMap to transform a every value in a partial map.

import { mapPartialMap } from "map-fns";

const map = {
  a: 1,
  b: 2,
  c: 3,
};

mapPartialMap(map, ["a", "c"], (n) => n * 10);
//=> {
//     a: 10,
//     c: 30,
//   }

Using mapPartialMap(map, keys, callback) is equivalent to using mapMap(partialMap(map, keys), callback).

import { mapPartialMap, mapMap, partialMap } from "map-fns";

const map = {
  a: 1,
  b: 2,
  c: 3,
};

mapPartialMap(map, ["a", "c"], (n) => n * 10);
//=> {
//     a: 10,
//     c: 30,
//   }

mapMap(partialMap(map, ["a", "c"]), (n) => n * 10);
//=> {
//     a: 10,
//     c: 30,
//   }

mapPartialMap exists to improve readability and ease-of-use.

mergeInMap

Examples of using mergeInMap .

Use mergeInMap to modify entries in a map deeply.

import { mergeInMap } from "map-fns";

const companies = {
  apple: {
    name: "Apple Inc.",
    headquarters: {
      country: "United States",
      address: "1 Apple Park Way",
    },
  },
  google: {
    name: "Google LLC",
    headquarters: {
      country: "United States",
      address: "1600 Amphitheatre Parkway",
    },
  },
};

// Move Google's headquarters

mergeInMap(companies, "google", {
  headquarters: {
    address: "50 Quantum Avenue St.",
  },
});
//=> {
//     apple: {
//       name: "Apple Inc.",
//       headquarters: {
//         country: "United States",
//         address: "1 Apple Park Way",
//       },
//     },
//     google: {
//       name: "Google LLC",
//       headquarters: {
//         country: "United States",
//         address: "1600 Amphitheatre Parkway",
//       },
//     },
//   }

Instead of providing a property directly, a callback can be provided:

import { mergeInMap } from "map-fns";

const departments = {
  engineering: {
    name: "Engineering",
    employees: ["Alex", "Brandon", "Caitlin"],
  },
  design: {
    name: "Design",
    employees: ["Daniela", "Evan"],
  },
};

// Let's welcome Francesca to the Design team

mergeInMap(departments, "design", {
  employees: (employees) => [...employees, "Francesca"],
});
//=> {
//     engineering: {
//       name: "Engineering",
//       employees: ["Alex", "Brandon", "Caitlin"],
//     },
//     design: {
//       name: "Design",
//       employees: ["Daniela", "Evan", "Francesca"],
//     },
//   }

By providing an array of keys, multiple entries in the map can be modified at once:

import { mergeInMap } from "map-fns";

const employees = {
  alice: {
    name: "Alice Thompson",
    salary: 160_000,
  },
  bob: {
    name: "Bob Smith",
    salary: 120_000,
  },
  charlie: {
    name: "Charlie Miller",
    salary: 145_000,
  },
};

// Give Alice and Bob a 10% raise

mergeInMap(employees, ["alice", "bob"], {
  salary: (salary) => salary * 1.1,
});
//=> {
//     alice: {
//       name: "Alice Thompson",
//       salary: 176_000,
//     },
//     bob: {
//       name: "Bob Smith",
//       salary: 132_000,
//     },
//     charlie: {
//       name: "Charlie Miller",
//       salary: 145_000,
//     },
//   }

modifyInMap

Examples of using modifyInMap .

Use modifyInMap to modify entries in a map.

import { modifyInMap } from "map-fns";

const map = {
  a: 1,
  b: 2,
  c: 3,
};

modifyInMap(map, "a", (n) => n * 10);
//=> {
//     a: 10,
//     b: 2,
//     c: 3,
//   }

Multiple entries can be modified by providing an array of keys as the second argument.

import { modifyInMap } from "map-fns";

const map = {
  a: 1,
  b: 2,
  c: 3,
};

modifyInMap(map, ["a", "c"], (n) => n * 10);
//=> {
//     a: 10,
//     b: 2,
//     c: 30,
//   }

partialMap

Examples of using partialMap .

Use partialMap to get a copy of a map only including the keys provided in the second argument.

import { partialMap } from "map-fns";

const map = {
  a: 1,
  b: 2,
  c: 3,
};

partialMap(map, ["a", "b"]);
//=> {
//     a: 1,
//     b: 2,
//   }

removeKeysFromMap

Examples of using removeKeysFromMap .

Use removeKeysFromMap to get a copy of a map excluding the keys provided in the second argument.

import { removeKeysFromMap } from "map-fns";

const map = {
  a: 1,
  b: 2,
  c: 3,
};

removeKeysFromMap(map, ["a", "c"]);
//=> {
//     b: 2,
//   }

If you only need to remove a single key from the map, that key may be provided directly as the second argument.

import { removeKeysFromMap } from "map-fns";

const map = {
  a: 1,
  b: 2,
  c: 3,
};

removeKeysFromMap(map, "c");
//=> {
//     a: 1,
//     b: 2,
//   }