Skip to content

Commit 5bc9629

Browse files
committed
Repo setup
0 parents  commit 5bc9629

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+4282
-0
lines changed

.github/workflows/test.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
name: test-${{ matrix.deno }}-${{ matrix.os }}
12+
runs-on: ${{ matrix.os }}
13+
14+
strategy:
15+
matrix:
16+
deno: [old, stable, canary]
17+
os: [macOS-latest, windows-latest, ubuntu-latest]
18+
19+
steps:
20+
- name: Setup repo
21+
uses: actions/checkout@v2
22+
23+
- name: Setup Deno
24+
run: |
25+
curl -fsSL https://deno.land/x/install/install.sh | sh ${{ matrix.deno == 'old' && '-s v1.35.0' || '' }}
26+
echo "$HOME/.deno/bin" >> $${{ runner.os == 'Windows' && 'env:' || '' }}GITHUB_PATH
27+
- name: Upgrade to Deno canary
28+
if: matrix.deno == 'canary'
29+
run: deno upgrade --canary
30+
31+
- name: Format
32+
if: runner.os == 'Linux'
33+
run: deno fmt --check
34+
35+
- name: Lint
36+
if: runner.os == 'Linux'
37+
run: deno lint --unstable
38+
39+
# - name: Run Tests
40+
# run: deno test --unstable --check -A

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.*
2+
!/.github
3+
!/.gitignore
4+
deno.lock

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# sorcery
2+
3+
Input, computation and output. That's all sorcery!
4+
5+
## Todo
6+
7+
Fix `collections` for strings and other iterables.
8+
9+
## Credit
10+
11+
https://github.com/sekwiatkowski

arrays/aggregation.js

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
import { equals } from "../booleans/equality.js";
2+
import { identity } from "../higher_order.js";
3+
import { defaultValue } from "../type.js";
4+
5+
/**
6+
* Takes a callback of three arguments (`acc`, `el`, `i`), an initial value and
7+
* an array. It returns an accumulated result.
8+
* ```ts
9+
* function toUpperCase(acc, el) {
10+
* console.log("el:", el);
11+
* return acc += el.toUpperCase();
12+
* }
13+
* const arrS = ["uno", "dos", "tres", "quattro", "cinco"];
14+
* fold(toUpperCase)("initialValue")(arrS);
15+
* ```
16+
*/
17+
function fold(f) {
18+
return (initialValue) => (arr) => {
19+
let acc = initialValue;
20+
21+
for (let i = 0; i < arr.length; i++) {
22+
acc = f(acc, arr[i], i);
23+
}
24+
25+
return acc;
26+
};
27+
}
28+
29+
/**
30+
* Takes a predicate of three arguments, a callback of three arguments, an initial
31+
* value and an array. It accumulates its result while the predicate returns `true`.
32+
* ```ts
33+
* foldWhile(isString)(toUpperCase)("initialValue")(arrS);
34+
* ```
35+
*/
36+
function foldWhile(predicate) {
37+
return (f) => (initialValue) => (arr) => {
38+
let acc = initialValue;
39+
40+
for (let i = 0; i < arr.length; i++) {
41+
const item = arr[i];
42+
if (!predicate(acc, item, i)) {
43+
return acc;
44+
}
45+
acc = f(acc, item, i);
46+
}
47+
return acc;
48+
};
49+
}
50+
51+
/**
52+
* Takes a callback of three arguments and an array. It uses the first element
53+
* of the array as initial value and returns an accumulated result.
54+
* ```ts
55+
* function add(a, b) {
56+
* return a + b;
57+
* }
58+
* const arrN = [10, 20, 30, 40, 50];
59+
* reduce(add)(arrN);
60+
* ```
61+
*/
62+
function reduce(f) {
63+
return (arr) => {
64+
let acc = arr[0];
65+
66+
for (let i = 1; i < arr.length; i++) {
67+
acc = f(acc, arr[i], i);
68+
}
69+
70+
return acc;
71+
};
72+
}
73+
74+
const count = countBy(identity);
75+
76+
/**
77+
* Creates an object composed of keys generated from the results of running each
78+
* element of collection thru iteratee. The corresponding value of each key is
79+
* the number of times the key was returned by iteratee.
80+
* @template I,N
81+
* @param {(item: I) => N} f
82+
* @returns {(arr: I[]) => Record<string, number>}
83+
*/
84+
function countBy(f) {
85+
return (arr) => {
86+
const counts = {};
87+
88+
for (const item of arr) {
89+
const key = f(item);
90+
const currentCount = defaultValue(0)(counts[key]);
91+
counts[key] = currentCount + 1;
92+
}
93+
94+
return counts;
95+
};
96+
}
97+
98+
/**
99+
* countIf.
100+
*
101+
* @param {} predicate
102+
*/
103+
function countIf(predicate) {
104+
return (arr) => {
105+
let counter = 0;
106+
107+
for (const item of arr) {
108+
if (predicate(item)) {
109+
counter += 1;
110+
}
111+
}
112+
113+
return counter;
114+
};
115+
}
116+
117+
/**
118+
* countOf.
119+
*
120+
* @param {} value
121+
*/
122+
function countOf(value) {
123+
return (arr) => countIf(equals(value))(arr);
124+
}
125+
126+
/**
127+
* min.
128+
*
129+
* @param {} arr
130+
*/
131+
function min(arr) {
132+
if (arguments.length > 1) {
133+
return min(Array.prototype.slice.call(arguments));
134+
}
135+
136+
return Math.min(...arr);
137+
}
138+
139+
/**
140+
* minBy.
141+
*
142+
* @param {} f
143+
*/
144+
function minBy(f) {
145+
return (arr) => {
146+
let lowestScore = Number.POSITIVE_INFINITY;
147+
let index = -1;
148+
149+
for (let i = 0; i < arr.length; i++) {
150+
const score = f(arr[i]);
151+
152+
if (score < lowestScore) {
153+
lowestScore = score;
154+
index = i;
155+
}
156+
}
157+
158+
return arr[index];
159+
};
160+
}
161+
162+
/**
163+
* max.
164+
*
165+
* @param {} arr
166+
*/
167+
function max(arr) {
168+
if (arguments.length > 1) {
169+
return max(Array.prototype.slice.call(arguments));
170+
}
171+
172+
return Math.max(...arr);
173+
}
174+
175+
/**
176+
* maxBy.
177+
*
178+
* @param {} f
179+
*/
180+
function maxBy(f) {
181+
return (arr) => {
182+
let highestScore = Number.NEGATIVE_INFINITY;
183+
let index = -1;
184+
185+
for (let i = 0; i < arr.length; i++) {
186+
const score = f(arr[i]);
187+
188+
if (score > highestScore) {
189+
highestScore = score;
190+
index = i;
191+
}
192+
}
193+
194+
return arr[index];
195+
};
196+
}
197+
198+
/**
199+
* sumBy.
200+
*
201+
* @param {} f
202+
*/
203+
function sumBy(f) {
204+
return (xs) => fold((acc, x) => acc + f(x))(0)(xs);
205+
}
206+
207+
const sum = sumBy(identity);
208+
209+
/**
210+
* productBy.
211+
*
212+
* @param {} f
213+
*/
214+
function productBy(f) {
215+
return (xs) => fold((acc, x) => acc * f(x))(1)(xs);
216+
}
217+
218+
const product = productBy(identity);
219+
220+
export {
221+
count,
222+
countBy,
223+
countIf,
224+
countOf,
225+
fold,
226+
foldWhile,
227+
max,
228+
maxBy,
229+
min,
230+
minBy,
231+
product,
232+
productBy,
233+
reduce,
234+
sum,
235+
sumBy,
236+
};

arrays/creation.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
function fill(value) {
2+
return (n) => {
3+
const result = Array(n);
4+
5+
for (let i = 0; i < n; i++) {
6+
result[i] = value;
7+
}
8+
9+
return result;
10+
};
11+
}
12+
13+
function fillWith1ToN(n) {
14+
return Array.from(Array(n).keys());
15+
}
16+
17+
function range(inclusiveStart) {
18+
return (exclusiveEnd) => {
19+
return steps(inclusiveStart)(exclusiveEnd)(1);
20+
};
21+
}
22+
23+
function inclusiveRange(inclusiveStart) {
24+
return (inclusiveEnd) => {
25+
return range(inclusiveStart)(inclusiveEnd + 1);
26+
};
27+
}
28+
29+
function steps(inclusiveStart) {
30+
return (exclusiveEnd) => (stepSize) => {
31+
const size = Math.ceil((exclusiveEnd - inclusiveStart) / stepSize);
32+
33+
if (size < 1) {
34+
return [];
35+
}
36+
37+
const result = Array(size);
38+
39+
for (
40+
let i = 0, current = inclusiveStart;
41+
i < size;
42+
i++, current += stepSize
43+
) {
44+
result[i] = current;
45+
}
46+
47+
return result;
48+
};
49+
}
50+
51+
function inclusiveSteps(inclusiveStart) {
52+
return (inclusiveEnd) => (stepSize) =>
53+
steps(inclusiveStart)(inclusiveEnd + 1)(stepSize);
54+
}
55+
56+
export { fill, fillWith1ToN, inclusiveRange, inclusiveSteps, range, steps };

0 commit comments

Comments
 (0)