import { pipe, type Predicate, type Refinement } from "./Function.js"
import * as Option from "./Option.js"
import * as Chunk from "effect/Chunk"
import { type Equivalence } from "effect/Equivalence"
import * as Array from "./Array.js"
export * from "effect/Chunk"
export const fromIterable = Chunk.fromIterable
export function groupByTChunk_(c: Chunk.Chunk, f: (a: A) => Key) {
return pipe(Chunk.toReadonlyArray(c), Array.groupByT(f), Chunk.fromIterable)
}
/**
* Returns the first element that satisfies the predicate.
*/
export function findFirstMap(
f: (a: A) => Option.Option
) {
return (as: Chunk.Chunk) => {
const ass = Chunk.toReadonlyArray(as)
const len = ass.length
for (let i = 0; i < len; i++) {
const v = f(ass[i]!)
if (Option.isSome(v)) {
return v
}
}
return Option.none()
}
}
export function toArray(c: Chunk.Chunk): T[] {
return Chunk.toReadonlyArray(c) as T[]
}
/**
* Remove duplicates from an array, keeping the first occurrence of an element.
*/
export function uniq(E: Equivalence) {
return (self: Chunk.Chunk): Chunk.Chunk => {
let out = Chunk.fromIterable([] as A[])
for (let i = 0; i < self.length; i++) {
const a = Chunk.getUnsafe(self, i)
if (!elem(E, a)(out)) {
out = Chunk.append(out, a)
}
}
return self.length === out.length ? self : out
}
}
/**
* Test if a value is a member of an array. Takes a `Equivalence` as a single
* argument which returns the function to use to search for a value of type `A`
* in an array of type `Chunk`.
*/
export function elem(E: Equivalence, value: A) {
return (self: Chunk.Chunk): boolean => {
for (let i = 0; i < self.length; i++) {
if (E(Chunk.getUnsafe(self, i), value)) {
return true
}
}
return false
}
}
export const ChunkPartition = Chunk.partition
export const findFirstSimple: {
(self: Chunk.Chunk, refinement: Refinement): Option.Option
(self: Chunk.Chunk, predicate: Predicate): Option.Option
} = Chunk.findFirst
export const findLastSimple: {
(self: Chunk.Chunk, refinement: Refinement): Option.Option
(self: Chunk.Chunk, predicate: Predicate): Option.Option
} = Chunk.findLast