Skip to content

Commit 6667e3a

Browse files
committed
Add util func to split over n delimiters
1 parent a239010 commit 6667e3a

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

packages/smithy-client/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ export * from "./isa";
66
export * from "./lazy-json";
77
export * from "./extended-encode-uri-component";
88
export * from "./date-utils";
9+
export * from "./split-every";
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { splitEvery } from "./split-every";
2+
describe("splitEvery", () => {
3+
const m1 = "foo";
4+
const m2 = "foo, bar";
5+
const m3 = "foo, bar, baz";
6+
const m4 = "foo, bar, baz, qux";
7+
const m5 = "foo, bar, baz, qux, coo";
8+
const m6 = "foo, bar, baz, qux, coo, tan";
9+
const delim = ", ";
10+
11+
it("Errors on <= 0", () => {
12+
expect(() => {
13+
splitEvery(m2, delim, -1)
14+
}).toThrow("Invalid number of delimiters");
15+
16+
expect(() => {
17+
splitEvery(m2, delim, 0)
18+
}).toThrow("Invalid number of delimiters");
19+
});
20+
21+
it("Errors on non-integer", () => {
22+
expect(() => {
23+
splitEvery(m2, delim, 1.3)
24+
}).toThrow("Invalid number of delimiters");
25+
26+
expect(() => {
27+
splitEvery(m2, delim, 4.9)
28+
}).toThrow("Invalid number of delimiters");
29+
})
30+
31+
it("Handles splitting on 1", () => {
32+
const count = 1;
33+
expect(splitEvery(m1, delim, count)).toMatchObject(m1.split(delim));
34+
expect(splitEvery(m2, delim, count)).toMatchObject(m2.split(delim));
35+
expect(splitEvery(m3, delim, count)).toMatchObject(m3.split(delim));
36+
expect(splitEvery(m4, delim, count)).toMatchObject(m4.split(delim));
37+
expect(splitEvery(m5, delim, count)).toMatchObject(m5.split(delim));
38+
expect(splitEvery(m6, delim, count)).toMatchObject(m6.split(delim));
39+
})
40+
41+
it("Handles splitting on 2", () => {
42+
const count = 2;
43+
expect(splitEvery(m1, delim, count)).toMatchObject(["foo"]);
44+
expect(splitEvery(m2, delim, count)).toMatchObject(["foo, bar"]);
45+
expect(splitEvery(m3, delim, count)).toMatchObject(["foo, bar", "baz"]);
46+
expect(splitEvery(m4, delim, count)).toMatchObject(["foo, bar", "baz, qux"]);
47+
expect(splitEvery(m5, delim, count)).toMatchObject(["foo, bar", "baz, qux", "coo"]);
48+
expect(splitEvery(m6, delim, count)).toMatchObject(["foo, bar", "baz, qux", "coo, tan"]);
49+
})
50+
51+
it("Handles splitting on 3", () => {
52+
const count = 3;
53+
expect(splitEvery(m1, delim, count)).toMatchObject(["foo"]);
54+
expect(splitEvery(m2, delim, count)).toMatchObject(["foo, bar"]);
55+
expect(splitEvery(m3, delim, count)).toMatchObject(["foo, bar, baz"]);
56+
expect(splitEvery(m4, delim, count)).toMatchObject(["foo, bar, baz", "qux"]);
57+
expect(splitEvery(m5, delim, count)).toMatchObject(["foo, bar, baz", "qux, coo"]);
58+
expect(splitEvery(m6, delim, count)).toMatchObject(["foo, bar, baz", "qux, coo, tan"]);
59+
})
60+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Given an input string, splits based on the delimiter after a given
3+
* number of delimiters has been encountered.
4+
*
5+
* @param value The input string to split.
6+
* @param delimiter The delimiter to split on.
7+
* @param numDelimiters The number of delimiters to have encountered to split.
8+
*/
9+
export function splitEvery(value: string, delimiter: string, numDelimiters: number): Array<string> {
10+
// Fail if we don't have a clear number to split on.
11+
if (numDelimiters <= 0 || !Number.isInteger(numDelimiters)) {
12+
throw new Error("Invalid number of delimiters (" + numDelimiters + ") for splitEvery.");
13+
}
14+
15+
const segments = value.split(delimiter);
16+
// Short circuit extra logic for the simple case.
17+
if (numDelimiters === 1) {
18+
return segments;
19+
}
20+
21+
const compoundSegments: Array<string> = [];
22+
let currentSegment = "";
23+
for (let i = 0; i < segments.length; i++) {
24+
if (currentSegment === "") {
25+
// Start a new segment.
26+
currentSegment = segments[i];
27+
} else {
28+
// Compound the current segment with the delimiter.
29+
currentSegment += delimiter + segments[i];
30+
}
31+
32+
if ((i + 1) % numDelimiters === 0) {
33+
// We encountered the right number of delimiters, so add the entry.
34+
compoundSegments.push(currentSegment);
35+
// And reset the current segment.
36+
currentSegment = "";
37+
}
38+
}
39+
40+
// Handle any leftover segment portion.
41+
if (currentSegment !== "") {
42+
compoundSegments.push(currentSegment);
43+
}
44+
45+
return compoundSegments;
46+
}

0 commit comments

Comments
 (0)