Skip to content

Instantly share code, notes, and snippets.

@emma-k-alexandra
Created January 17, 2024 03:27
Show Gist options
  • Save emma-k-alexandra/b679d71e2a6acd8b5c37bd9c6089d883 to your computer and use it in GitHub Desktop.
Save emma-k-alexandra/b679d71e2a6acd8b5c37bd9c6089d883 to your computer and use it in GitHub Desktop.
Fun with Object.groupBy and Map.groupBy
/**
* This is a fun attempt to implement a `zip` function using the new Object.groupBy and Map.groupBy functions because I hate index math.
*/
/**
* A silly implementation of zip using [Object.groupBy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/groupBy).
*
* It's zip! Great explanation here of the Python implementation (which is better than this one)
* @see https://docs.python.org/3.3/library/functions.html#zip
*
* @param {...any[]} lists Your arrays to zip
* @returns {[...any[]]} An array where the i-th element contains all of the i-th elements from the given arrays
*
* @remarks
* This implementation is just for fun. Pick some better implementation for your production application like [itertools-ts](https://www.npmjs.com/package/itertools-ts).
*/
const zip = (...lists) => Array.from(
Object.values(
Object.groupBy(
lists.flatMap(list => [...list.entries()]),
([index]) => index
)
),
group => group.map(([, value]) => value)
)
/**
* The same as {@link zip} but using [Map.groupBy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/groupBy).
*
* @param {...any[]} lists Your arrays to zip
* @returns {[...any[]]} An array where the i-th element contains all of the i-th elements from the given arrays
*/
const zipWithMap = (...lists) => Array.from(
Map.groupBy(
lists.flatMap(list => [...list.entries()]),
([ index ]) => index
).values(),
group => group.map(([ , value ]) => value)
)
const simpleLists = [
['a', 'b', 'c'],
['d', 'e', 'f'],
]
/**
* Example 1
*
* Returns:
* ```js
* [
* ["a","d"],
* ["b","e"],
* ["c","f"]
* ]
* ```
*
* Step by Step:
* const entries = lists.flatMap(list => [...list.entries()]) // [[0, "a"], [1, "b"], [2, "c"], [0, "d"], [1, "e"], [2, "f"]]
* const groups = Object.groupBy(entries, ([index]) => index) // { 0: [[0, "a"], [0, "d"]], 1: [[1, "b"], [1, "d"]], 2: [[2, "c"], [2, "f"]] }
* const groupsAsArray = Object.values(groups) // [[[0, "a"], [0, "d"]], [[1, "b"], [1, "d"]], [[2, "c"], [2, "f"]]]
* Array.from(groupsAsArray, group => group.map(([, value]) => value)) // [["a", "d"], ["b", "d"], ["c", "f"]]
*/
zip(simpleLists)
const lists = [
['a', 'b', 'c'],
['d', 'e', 'f', 'g', 'h'],
['i'],
['j', 'k', 'k']
]
/**
* Example 2
*
* Returns:
* ```js
* [
* ["a", "d", "i", "j"],
* ["b", "e", "k"],
* ["c", "f", "k"],
* ["g"],
* ["h"]
* ]
* ```
*/
zipWithMap(lists)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment