Skip to content

Commit 93b412d

Browse files
gcantimikearnaldi
authored andcommittedFeb 21, 2024
ReadonlyArray.groupBy: allow for grouping by symbols, closes #2180 (#2181)
1 parent 983892f commit 93b412d

File tree

4 files changed

+42
-8
lines changed

4 files changed

+42
-8
lines changed
 

‎.changeset/light-mangos-punch.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect": patch
3+
---
4+
5+
ReadonlyArray.groupBy: allow for grouping by symbols, closes #2180

‎packages/effect/dtslint/ReadonlyArray.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ declare const pimitiveNumber: number
1919
declare const pimitiveNumerOrString: string | number
2020
declare const predicateNumbersOrStrings: Predicate.Predicate<number | string>
2121

22+
const symA = Symbol.for("a")
23+
const symB = Symbol.for("b")
24+
const symC = Symbol.for("c")
25+
2226
// -------------------------------------------------------------------------------------
2327
// isEmptyReadonlyArray
2428
// -------------------------------------------------------------------------------------
@@ -99,14 +103,18 @@ pipe(nonEmptyNumbers, ReadonlyArray.map((n) => n + 1))
99103
// groupBy
100104
// -------------------------------------------------------------------------------------
101105

102-
// baseline
103106
// $ExpectType Record<string, [number, ...number[]]>
104107
ReadonlyArray.groupBy([1, 2, 3], String)
105108

106-
// should not return a struct (Record<'positive' | 'negative', ...>) when using string type literals
107109
// $ExpectType Record<string, [number, ...number[]]>
108110
ReadonlyArray.groupBy([1, 2, 3], (n) => n > 0 ? "positive" as const : "negative" as const)
109111

112+
// $ExpectType Record<symbol, [string, ...string[]]>
113+
ReadonlyArray.groupBy(["a", "b"], Symbol.for)
114+
115+
// $ExpectType Record<symbol, [string, ...string[]]>
116+
ReadonlyArray.groupBy(["a", "b"], (s) => s === "a" ? symA : s === "b" ? symB : symC)
117+
110118
// -------------------------------------------------------------------------------------
111119
// some
112120
// -------------------------------------------------------------------------------------

‎packages/effect/src/ReadonlyArray.ts

+14-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import * as O from "./Option.js"
1717
import * as Order from "./Order.js"
1818
import type { Predicate, Refinement } from "./Predicate.js"
1919
import { isBoolean } from "./Predicate.js"
20-
import * as RR from "./ReadonlyRecord.js"
20+
import * as ReadonlyRecord from "./ReadonlyRecord.js"
2121
import * as Tuple from "./Tuple.js"
2222
import type { NoInfer } from "./Types.js"
2323

@@ -128,7 +128,7 @@ export const fromIterable = <A>(collection: Iterable<A>): Array<A> =>
128128
* @category conversions
129129
* @since 2.0.0
130130
*/
131-
export const fromRecord: <K extends string, A>(self: Readonly<Record<K, A>>) => Array<[K, A]> = RR.toEntries
131+
export const fromRecord: <K extends string, A>(self: Readonly<Record<K, A>>) => Array<[K, A]> = ReadonlyRecord.toEntries
132132

133133
/**
134134
* @category conversions
@@ -1334,10 +1334,18 @@ export const group: <A>(self: NonEmptyReadonlyArray<A>) => NonEmptyArray<NonEmpt
13341334
* @since 2.0.0
13351335
*/
13361336
export const groupBy: {
1337-
<A>(f: (a: A) => string): (self: Iterable<A>) => Record<string, NonEmptyArray<A>>
1338-
<A>(self: Iterable<A>, f: (a: A) => string): Record<string, NonEmptyArray<A>>
1339-
} = dual(2, <A>(self: Iterable<A>, f: (a: A) => string): Record<string, NonEmptyArray<A>> => {
1340-
const out: Record<string, NonEmptyArray<A>> = {}
1337+
<A, K extends string | symbol>(
1338+
f: (a: A) => K
1339+
): (self: Iterable<A>) => Record<ReadonlyRecord.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>
1340+
<A, K extends string | symbol>(
1341+
self: Iterable<A>,
1342+
f: (a: A) => K
1343+
): Record<ReadonlyRecord.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>>
1344+
} = dual(2, <A, K extends string | symbol>(
1345+
self: Iterable<A>,
1346+
f: (a: A) => K
1347+
): Record<ReadonlyRecord.ReadonlyRecord.NonLiteralKey<K>, NonEmptyArray<A>> => {
1348+
const out: Record<string | symbol, NonEmptyArray<A>> = {}
13411349
for (const a of self) {
13421350
const k = f(a)
13431351
if (Object.prototype.hasOwnProperty.call(out, k)) {

‎packages/effect/test/ReadonlyArray.test.ts

+13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import * as String from "effect/String"
1010
import * as fc from "fast-check"
1111
import { assert, describe, expect, it } from "vitest"
1212

13+
const symA = Symbol.for("a")
14+
const symB = Symbol.for("b")
15+
const symC = Symbol.for("c")
16+
1317
describe("ReadonlyArray", () => {
1418
it("exports", () => {
1519
expect(RA.fromRecord).exist
@@ -971,6 +975,15 @@ describe("ReadonlyArray", () => {
971975
"6": ["foobar"]
972976
}
973977
)
978+
expect(RA.groupBy(["a", "b"], (s) => s === "a" ? symA : s === "b" ? symB : symC)).toStrictEqual({
979+
[symA]: ["a"],
980+
[symB]: ["b"]
981+
})
982+
expect(RA.groupBy(["a", "b", "c", "d"], (s) => s === "a" ? symA : s === "b" ? symB : symC)).toStrictEqual({
983+
[symA]: ["a"],
984+
[symB]: ["b"],
985+
[symC]: ["c", "d"]
986+
})
974987
})
975988

976989
it("match", () => {

0 commit comments

Comments
 (0)
Please sign in to comment.