<A, K extends string | symbol>(f: (a: A) => K): (
self: Iterable<A>
) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>
<A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<
Record.ReadonlyRecord.NonLiteralKey<K>,
NonEmptyArray<A>
>Groups all elements by the string or symbol key returned by f.
Details
Each property in the returned record contains a non-empty array of elements
that produced that key. Unlike group, matching elements do not need to be
consecutive.
Example (Grouping by a key)
import { Iterable } from "effect"
// Group by string length
const words = ["a", "bb", "ccc", "dd", "eee", "f"]
const byLength = Iterable.groupBy(words, (word) => word.length.toString())
console.log(byLength)
// { "1": ["a", "f"], "2": ["bb", "dd"], "3": ["ccc", "eee"] }
// Group by first letter
const names = ["Alice", "Bob", "Charlie", "David", "Anna", "Betty"]
const byFirstLetter = Iterable.groupBy(names, (name) => name[0])
console.log(byFirstLetter)
// { "A": ["Alice", "Anna"], "B": ["Bob", "Betty"], "C": ["Charlie"], "D": ["David"] }
// Group by category
const items = [
{ name: "apple", category: "fruit" },
{ name: "carrot", category: "vegetable" },
{ name: "banana", category: "fruit" },
{ name: "broccoli", category: "vegetable" }
]
const byCategory = Iterable.groupBy(items, (item) => item.category)
console.log(byCategory)
// {
// "fruit": [{ name: "apple", category: "fruit" }, { name: "banana", category: "fruit" }],
// "vegetable": [{ name: "carrot", category: "vegetable" }, { name: "broccoli", category: "vegetable" }]
// }
// Group numbers by even/odd
const numbers = [1, 2, 3, 4, 5, 6]
const evenOdd = Iterable.groupBy(numbers, (n) => n % 2 === 0 ? "even" : "odd")
console.log(evenOdd)
// { "odd": [1, 3, 5], "even": [2, 4, 6] }export const const groupBy: {
<A, K extends string | symbol>(
f: (a: A) => K
): (
self: Iterable<A>
) => Record<
Record.ReadonlyRecord.NonLiteralKey<K>,
NonEmptyArray<A>
>
<A, K extends string | symbol>(
self: Iterable<A>,
f: (a: A) => K
): Record<
Record.ReadonlyRecord.NonLiteralKey<K>,
NonEmptyArray<A>
>
}
Groups all elements by the string or symbol key returned by f.
Details
Each property in the returned record contains a non-empty array of elements
that produced that key. Unlike group, matching elements do not need to be
consecutive.
Example (Grouping by a key)
import { Iterable } from "effect"
// Group by string length
const words = ["a", "bb", "ccc", "dd", "eee", "f"]
const byLength = Iterable.groupBy(words, (word) => word.length.toString())
console.log(byLength)
// { "1": ["a", "f"], "2": ["bb", "dd"], "3": ["ccc", "eee"] }
// Group by first letter
const names = ["Alice", "Bob", "Charlie", "David", "Anna", "Betty"]
const byFirstLetter = Iterable.groupBy(names, (name) => name[0])
console.log(byFirstLetter)
// { "A": ["Alice", "Anna"], "B": ["Bob", "Betty"], "C": ["Charlie"], "D": ["David"] }
// Group by category
const items = [
{ name: "apple", category: "fruit" },
{ name: "carrot", category: "vegetable" },
{ name: "banana", category: "fruit" },
{ name: "broccoli", category: "vegetable" }
]
const byCategory = Iterable.groupBy(items, (item) => item.category)
console.log(byCategory)
// {
// "fruit": [{ name: "apple", category: "fruit" }, { name: "banana", category: "fruit" }],
// "vegetable": [{ name: "carrot", category: "vegetable" }, { name: "broccoli", category: "vegetable" }]
// }
// Group numbers by even/odd
const numbers = [1, 2, 3, 4, 5, 6]
const evenOdd = Iterable.groupBy(numbers, (n) => n % 2 === 0 ? "even" : "odd")
console.log(evenOdd)
// { "odd": [1, 3, 5], "even": [2, 4, 6] }
groupBy: {
<function (type parameter) A in <A, K extends string | symbol>(f: (a: A) => K): (self: Iterable<A>) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A, function (type parameter) K in <A, K extends string | symbol>(f: (a: A) => K): (self: Iterable<A>) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>K extends string | symbol>(
f: (a: A) => Kf: (a: Aa: function (type parameter) A in <A, K extends string | symbol>(f: (a: A) => K): (self: Iterable<A>) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A) => function (type parameter) K in <A, K extends string | symbol>(f: (a: A) => K): (self: Iterable<A>) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>K
): (self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, K extends string | symbol>(f: (a: A) => K): (self: Iterable<A>) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A>) => type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<import RecordRecord.ReadonlyRecord.type ReadonlyRecord<in out K extends string | symbol, out A>.NonLiteralKey<K extends string | symbol> = K extends string ? Record.ReadonlyRecord.IsFiniteString<K> extends true ? string : K : symbolRepresents a type that converts literal string keys to generic string type and symbol keys to generic symbol type.
This is useful for maintaining type safety while allowing flexible key types in record operations.
Example (Converting literal keys to non-literal keys)
import type { Record } from "effect"
// For literal string keys, this becomes 'string'
type Example1 = Record.ReadonlyRecord.NonLiteralKey<"foo" | "bar"> // string
// For symbol keys, this becomes 'symbol'
type Example2 = Record.ReadonlyRecord.NonLiteralKey<symbol> // symbol
NonLiteralKey<function (type parameter) K in <A, K extends string | symbol>(f: (a: A) => K): (self: Iterable<A>) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>K>, import NonEmptyArrayNonEmptyArray<function (type parameter) A in <A, K extends string | symbol>(f: (a: A) => K): (self: Iterable<A>) => Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A>>
<function (type parameter) A in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A, function (type parameter) K in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>K extends string | symbol>(
self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A>,
f: (a: A) => Kf: (a: Aa: function (type parameter) A in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A) => function (type parameter) K in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>K
): type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<import RecordRecord.ReadonlyRecord.type ReadonlyRecord<in out K extends string | symbol, out A>.NonLiteralKey<K extends string | symbol> = K extends string ? Record.ReadonlyRecord.IsFiniteString<K> extends true ? string : K : symbolRepresents a type that converts literal string keys to generic string type and symbol keys to generic symbol type.
This is useful for maintaining type safety while allowing flexible key types in record operations.
Example (Converting literal keys to non-literal keys)
import type { Record } from "effect"
// For literal string keys, this becomes 'string'
type Example1 = Record.ReadonlyRecord.NonLiteralKey<"foo" | "bar"> // string
// For symbol keys, this becomes 'symbol'
type Example2 = Record.ReadonlyRecord.NonLiteralKey<symbol> // symbol
NonLiteralKey<function (type parameter) K in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>K>, import NonEmptyArrayNonEmptyArray<function (type parameter) A in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A>>
} = import dualdual(2, <function (type parameter) A in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A, function (type parameter) K in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>K extends string | symbol>(
self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A>,
f: (a: A) => Kf: (a: Aa: function (type parameter) A in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A) => function (type parameter) K in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>K
): type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<import RecordRecord.ReadonlyRecord.type ReadonlyRecord<in out K extends string | symbol, out A>.NonLiteralKey<K extends string | symbol> = K extends string ? Record.ReadonlyRecord.IsFiniteString<K> extends true ? string : K : symbolRepresents a type that converts literal string keys to generic string type and symbol keys to generic symbol type.
This is useful for maintaining type safety while allowing flexible key types in record operations.
Example (Converting literal keys to non-literal keys)
import type { Record } from "effect"
// For literal string keys, this becomes 'string'
type Example1 = Record.ReadonlyRecord.NonLiteralKey<"foo" | "bar"> // string
// For symbol keys, this becomes 'symbol'
type Example2 = Record.ReadonlyRecord.NonLiteralKey<symbol> // symbol
NonLiteralKey<function (type parameter) K in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>K>, import NonEmptyArrayNonEmptyArray<function (type parameter) A in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A>> => {
const const out: Record<
string | symbol,
NonEmptyArray<A>
>
out: type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<string | symbol, import NonEmptyArrayNonEmptyArray<function (type parameter) A in <A, K extends string | symbol>(self: Iterable<A>, f: (a: A) => K): Record<Record.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>A>> = {}
for (const const a: Aa of self: Iterable<A>self) {
const const k: K extends string | symbolk = f: (a: A) => Kf(const a: Aa)
if (var Object: ObjectConstructorProvides functionality common to all JavaScript objects.
Object.ObjectConstructor.hasOwn(o: object, v: PropertyKey): booleanDetermines whether an object has a property with the specified name.
hasOwn(const out: Record<
string | symbol,
NonEmptyArray<A>
>
out, const k: string | symbolk)) {
const out: Record<
string | symbol,
NonEmptyArray<A>
>
out[const k: K extends string | symbolk].push(const a: Aa)
} else {
const out: Record<
string | symbol,
NonEmptyArray<A>
>
out[const k: K extends string | symbolk] = [const a: Aa]
}
}
return const out: Record<
string | symbol,
NonEmptyArray<A>
>
out
})