Skip to content

Commit

Permalink
part-before part-after (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
phunanon committed Jul 23, 2023
1 parent 3a0c026 commit a3dcb29
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 18 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,16 @@ etc
;Calls are (f i) for vector items or characters
(part-when odd? [0 2 4 5 6 8 9 0]) → [[0 2 4] [6 8 9 0]]

;Partitions by a function return into a vector of [before-true true-and-after]
; vectors for vector items or substrings.
;Calls are (f i) for vector items or characters
(part-before odd? [0 2 4 5 6 8 9 0]) → [[0 2 4] [5 6 8 9 0]]

;Partitions by a function return into a vector of [true-and-before after-true]
; vectors for vector items or substrings.
;Calls are (f i) for vector items or characters
(part-after odd? [0 2 4 5 6 8 9 0]) → [[0 2 4 5] [6 8 9 0]]

;Returns a vector partitioned into vectors or strings with N items/chars at most
(partition 2 (range 8)) → [[0 1] [2 3] [4 5] [6 7]]
(partition 3 "Hello, world!") → ["Hel" "lo," " wo" "rld" "!"]
Expand Down
45 changes: 27 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -858,34 +858,43 @@ function exeOp(op: string, args: Val[], ctx: Ctx, errCtx: ErrCtx): Val {
return _vec(parted.map(_vec));
}
}
case "part-when": {
case "part-when":
case "part-before":
case "part-after": {
const closure = getExe(ctx, args[0], errCtx);
const src = asArray(args[1]);
const isStr = args[1].t === "str";
let wasTrue = false;
if (isStr) {
const forStr = () => {
const parted: string[] = ["", ""];
for (let i = 0, lim = len(src); i < lim; ++i) {
const p = asBoo(closure([src[i]]));
if (p && !wasTrue) {
wasTrue = true;
continue;
}
parted[wasTrue ? 1 : 0] += str(src[i]);
}
return _vec(parted.map(_str));
} else {
return {
append: (s: Val) => (parted[wasTrue ? 1 : 0] += str(s)),
pack: () => _vec(parted.map(_str)),
};
};
const forVec = () => {
const parted: Val[][] = [[], []];
for (let i = 0, lim = len(src); i < lim; ++i) {
const p = asBoo(closure([src[i]]));
if (p && !wasTrue) {
wasTrue = true;
return {
append: (v: Val) => parted[wasTrue ? 1 : 0].push(v),
pack: () => _vec(parted.map(_vec)),
};
};
const { append, pack } = (isStr ? forStr : forVec)();
for (let i = 0, lim = len(src); i < lim; ++i) {
const p = asBoo(closure([src[i]]));
const now = p && !wasTrue;
if (now && op !== "part-after") {
wasTrue = true;
if (op === "part-when") {
continue;
}
parted[wasTrue ? 1 : 0].push(src[i]);
}
return _vec(parted.map(_vec));
append(src[i]);
if (now && op === "part-after") {
wasTrue = true;
}
}
return pack();
}
case "partition": {
const n = num(args[0]);
Expand Down
10 changes: 10 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,16 @@ export const ops: {
params: ["any", ["vec", "dict", "str"]],
returns: ["vec"],
},
"part-before": {
exactArity: 2,
params: ["any", ["vec", "dict", "str"]],
returns: ["vec"],
},
"part-after": {
exactArity: 2,
params: ["any", ["vec", "dict", "str"]],
returns: ["vec"],
},
partition: {
exactArity: 2,
params: ["num", ["vec", "str"]],
Expand Down

0 comments on commit a3dcb29

Please sign in to comment.