Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
395a6eb
Initialize package.json
przemyslawzalewski Oct 3, 2019
2e1cc11
Enable prettier
przemyslawzalewski Oct 3, 2019
d7886e9
Declare package type and no side effects
przemyslawzalewski Oct 3, 2019
5a3d0d4
Add initial helpers
przemyslawzalewski Oct 3, 2019
512d777
Use proper file extensions for import statements
przemyslawzalewski Oct 3, 2019
f94f7ab
Remove duplicated import
przemyslawzalewski Oct 3, 2019
e5f22df
Generate indices
przemyslawzalewski Oct 3, 2019
cffbcd7
Point module field to index file
przemyslawzalewski Oct 3, 2019
02760fd
Remove not ready modules
przemyslawzalewski Oct 3, 2019
2300673
Use strict equal comparison
przemyslawzalewski Oct 3, 2019
83fe1f5
Prepare package build scripts and setup
przemyslawzalewski Oct 3, 2019
d21606f
Fix broken and missing imports/exports
przemyslawzalewski Oct 3, 2019
bf6bb95
Ignore build output files
przemyslawzalewski Oct 3, 2019
bca8364
Fix broken default exports and add missing import
przemyslawzalewski Oct 3, 2019
6d903ab
Add another missing import
przemyslawzalewski Oct 3, 2019
446452d
Add missing helpers
przemyslawzalewski Oct 4, 2019
c3aef80
Add missing import
przemyslawzalewski Oct 4, 2019
a67a111
Add missing imports
przemyslawzalewski Oct 4, 2019
c31632d
Add missing range import for repeat
przemyslawzalewski Oct 4, 2019
f3dc2a2
Fix range/split recursion and make clamp calls consistent
przemyslawzalewski Oct 4, 2019
4bf3101
Fix missing toString helper issue
przemyslawzalewski Oct 4, 2019
477c240
docs: update README.md
allcontributors[bot] Oct 7, 2019
62dfd9f
docs: create .all-contributorsrc
allcontributors[bot] Oct 7, 2019
dd46940
Merge pull request #2 from sandstreamdev/all-contributors/add-sandstr…
Oct 7, 2019
b39b5c4
Use Array.fill directly to generate repeated values
przemyslawzalewski Oct 7, 2019
19c987c
Use consistent any/none object and array APIs
przemyslawzalewski Oct 7, 2019
83f23da
Improve adjust exact and range implementation
przemyslawzalewski Oct 7, 2019
b40fc5c
Add missing import
przemyslawzalewski Oct 7, 2019
175ae7b
Use isDefined helper
przemyslawzalewski Oct 7, 2019
288bafd
Initialize package.json
przemyslawzalewski Oct 3, 2019
036d35b
Enable prettier
przemyslawzalewski Oct 3, 2019
e8c6b69
Declare package type and no side effects
przemyslawzalewski Oct 3, 2019
1f919ff
Add initial helpers
przemyslawzalewski Oct 3, 2019
476327a
Use proper file extensions for import statements
przemyslawzalewski Oct 3, 2019
329dab5
Remove duplicated import
przemyslawzalewski Oct 3, 2019
e995e9f
Generate indices
przemyslawzalewski Oct 3, 2019
4b83314
Point module field to index file
przemyslawzalewski Oct 3, 2019
bd6b135
Remove not ready modules
przemyslawzalewski Oct 3, 2019
ea8a3ba
Use strict equal comparison
przemyslawzalewski Oct 3, 2019
c3470ec
Prepare package build scripts and setup
przemyslawzalewski Oct 3, 2019
ba709d0
Fix broken and missing imports/exports
przemyslawzalewski Oct 3, 2019
8e883fb
Ignore build output files
przemyslawzalewski Oct 3, 2019
de232d9
Fix broken default exports and add missing import
przemyslawzalewski Oct 3, 2019
0e569d0
Add another missing import
przemyslawzalewski Oct 3, 2019
4881f5f
Add missing helpers
przemyslawzalewski Oct 4, 2019
8911d90
Add missing import
przemyslawzalewski Oct 4, 2019
990589d
Add missing imports
przemyslawzalewski Oct 4, 2019
13ffd95
Add missing range import for repeat
przemyslawzalewski Oct 4, 2019
d798b98
Fix range/split recursion and make clamp calls consistent
przemyslawzalewski Oct 4, 2019
b299bb8
Fix missing toString helper issue
przemyslawzalewski Oct 4, 2019
56357f5
Use Array.fill directly to generate repeated values
przemyslawzalewski Oct 7, 2019
c056f7e
Use consistent any/none object and array APIs
przemyslawzalewski Oct 7, 2019
89488a4
Improve adjust exact and range implementation
przemyslawzalewski Oct 7, 2019
f31a2e0
Add missing import
przemyslawzalewski Oct 7, 2019
1088a05
Use isDefined helper
przemyslawzalewski Oct 7, 2019
19aac26
Merge branch 'initial' of https://github.com/sandstreamdev/std into i…
przemyslawzalewski Oct 7, 2019
011e83a
Add array difference and boolean function inversion
przemyslawzalewski Oct 8, 2019
e101e40
Add unique helper
przemyslawzalewski Oct 8, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"files": [
"README.md"
],
"imageSize": 100,
"commit": false,
"contributors": [
{
"login": "sandstreamdevelopment",
"name": "sandstreamdevelopment",
"avatar_url": "https://avatars2.githubusercontent.com/u/44231396?v=4",
"profile": "https://github.com/sandstreamdevelopment",
"contributions": [
"business",
"financial",
"ideas"
]
}
],
"contributorsPerLine": 7,
"projectName": "std",
"projectOwner": "sandstreamdev",
"repoType": "github",
"repoHost": "https://github.com"
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,6 @@ typings/

# next.js build output
.next

index.cjs.js
index.umd.js
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
regenerate.js
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,19 @@
# std
# std

[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors)

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore -->
<table>
<tr>
<td align="center"><a href="https://github.com/sandstreamdevelopment"><img src="https://avatars2.githubusercontent.com/u/44231396?v=4" width="100px;" alt="sandstreamdevelopment"/><br /><sub><b>sandstreamdevelopment</b></sub></a><br /><a href="#business-sandstreamdevelopment" title="Business development">💼</a> <a href="#financial-sandstreamdevelopment" title="Financial">💵</a> <a href="#ideas-sandstreamdevelopment" title="Ideas, Planning, & Feedback">🤔</a></td>
</tr>
</table>

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
1 change: 1 addition & 0 deletions array/any.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default xs => xs && xs.length > 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if the any is a good name for the function which checks if a provided array is not empty.

Any in many other languages do more than simply not empty check. For example they check, if any element of the array meets the provided condition or checks if there is any not null and not false element.
E.g:

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JavaScript already have this as Array.prototype.some. The any(xs) call is equal to C#'s xs.Any() parameterless overload.
The some/every are commonly used and well supported (IE9+) native Array APIs so IMHO no need to duplicate that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly :) As my first sentence in the comment: I'm thinking about the different name than any for that method

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I try to avoid empty/isEmpty to avoid conflict with the empty definition ([] for array, {} for object). However, I consider dropping them to use empty as a test function. But there is a naming issue of symmetric function - nonEmpty? I would like to avoid joined names and just stick with single-word names where possible. For now, it is any and none.
One more thing, the functions handle missing argument case, so: any(null) = false, any(undefined) = false, any(0) = false, array.any([]) = false, object.any({}) = false etc.

3 changes: 3 additions & 0 deletions array/are.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import is from "./is.js";

export default (...xs) => xs.every(is);
5 changes: 5 additions & 0 deletions array/difference.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default (xs, ys) => {
const zs = new Set(ys);

return xs.filter(x => !zs.has(x));
};
5 changes: 5 additions & 0 deletions array/differs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default (xs, ys) =>
(!xs && ys) ||
(!ys && xs) ||
xs.length !== ys.length ||
xs.some((x, index) => x !== ys[index]);
2 changes: 2 additions & 0 deletions array/duplicates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default xs =>
xs.filter((value, index, self) => self.indexOf(value) !== index);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please correct me if I'm wrong - what is the intent of this function?

  • Do we expect to return all duplicates?
    e.g. for [1, 1, 1, 1, 2] we expect to get [1, 1, 1, 1]
  • Or we expect to get unique duplicates - in that case [1]
  • Or we expect to get all duplicates minus one ;), what does the current implementation do ;) - it returns [1, 1, 1].

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It returns the duplicated values (values that occur more than once). A single law this function must obey is that a set of unique elements and the duplicates of some set is equal to itself:

equal(
  sort([...unique(xs), ...duplicates(xs)]),
  sort(xs)
)

By that, the only correct interpretation is the last definition - it returns a list of values that occurs more than once.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, good to know the idea, which you had behind that function - definitely we are missing docs. So.. maybe we should add unique helper?

1 change: 1 addition & 0 deletions array/empty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default [];
3 changes: 3 additions & 0 deletions array/exact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import range from "./range.js";

export default n => xs => range(n).map(index => xs[index]);
1 change: 1 addition & 0 deletions array/except.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default y => xs => xs.filter(x => x !== y);
15 changes: 15 additions & 0 deletions array/filterInPlace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default f => xs => {
let i = 0;
let j = 0;

while (i < xs.length) {
const value = xs[i];
if (f(value, i, xs)) {
xs[j++] = value;
}
i++;
}

xs.length = j;
return xs;
};
4 changes: 4 additions & 0 deletions array/find.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default (predicate, fallback) => xs => {
const target = xs.find(predicate);
return target !== undefined ? target : fallback;
};
1 change: 1 addition & 0 deletions array/first.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default ([x]) => x;
1 change: 1 addition & 0 deletions array/flatMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default f => xs => xs.reduce((ys, y) => ys.concat(f(y)), []);
1 change: 1 addition & 0 deletions array/flatten.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default xs => [].concat(...xs);
126 changes: 126 additions & 0 deletions array/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import any from "./any.js";
import are from "./are.js";
import difference from "./difference.js";
import differs from "./differs.js";
import duplicates from "./duplicates.js";
import empty from "./empty.js";
import exact from "./exact.js";
import except from "./except.js";
import filterInPlace from "./filterInPlace.js";
import find from "./find.js";
import first from "./first.js";
import flatMap from "./flatMap.js";
import flatten from "./flatten.js";
import intersection from "./intersection.js";
import is from "./is.js";
import last from "./last.js";
import lengthDiffers from "./lengthDiffers.js";
import map from "./map.js";
import midpoint from "./midpoint.js";
import minMax from "./minMax.js";
import multiple from "./multiple.js";
import none from "./none.js";
import partition from "./partition.js";
import range from "./range.js";
import repeat from "./repeat.js";
import reverse from "./reverse.js";
import reverseIf from "./reverseIf.js";
import rotate from "./rotate.js";
import second from "./second.js";
import secondToLast from "./secondToLast.js";
import shift from "./shift.js";
import shuffle from "./shuffle.js";
import shuffleInPlace from "./shuffleInPlace.js";
import single from "./single.js";
import sort from "./sort.js";
import sum from "./sum.js";
import transpose from "./transpose.js";
import unique from "./unique.js";
import zip from "./zip.js";
import zipWith from "./zipWith.js";

export {
any,
are,
difference,
differs,
duplicates,
empty,
exact,
except,
filterInPlace,
find,
first,
flatMap,
flatten,
intersection,
is,
last,
lengthDiffers,
map,
midpoint,
minMax,
multiple,
none,
partition,
range,
repeat,
reverse,
reverseIf,
rotate,
second,
secondToLast,
shift,
shuffle,
shuffleInPlace,
single,
sort,
sum,
transpose,
unique,
zip,
zipWith
};

export default {
any,
are,
difference,
differs,
duplicates,
empty,
exact,
except,
filterInPlace,
find,
first,
flatMap,
flatten,
intersection,
is,
last,
lengthDiffers,
map,
midpoint,
minMax,
multiple,
none,
partition,
range,
repeat,
reverse,
reverseIf,
rotate,
second,
secondToLast,
shift,
shuffle,
shuffleInPlace,
single,
sort,
sum,
transpose,
unique,
zip,
zipWith
};
1 change: 1 addition & 0 deletions array/intersection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default (xs, ys) => xs.filter(value => ys.includes(value));
1 change: 1 addition & 0 deletions array/is.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default value => Array.isArray(value);
1 change: 1 addition & 0 deletions array/last.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default xs => xs[xs.length - 1];
1 change: 1 addition & 0 deletions array/lengthDiffers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default (a, b) => a.length !== b.length;
4 changes: 4 additions & 0 deletions array/map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default (...fs) => {
const f = x => fs.reduce((x, f) => f(x), x);
return x => x.map(f);
};
1 change: 1 addition & 0 deletions array/midpoint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default xs => xs[Math.floor(xs.length / 2)];
7 changes: 7 additions & 0 deletions array/minMax.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const { max, min } = Math;

export default ([head, ...tail]) =>
tail.reduce(([min, max], current) => [min(min, current), max(max, current)], [
head,
head
]);
1 change: 1 addition & 0 deletions array/multiple.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default xs => xs.length > 1;
3 changes: 3 additions & 0 deletions array/none.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import any from "./any.js";

export default xs => !any(xs);
8 changes: 8 additions & 0 deletions array/partition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default predicate => xs =>
xs.reduce(
([left, right], current) => {
const pass = predicate(current);
return pass ? [left, [...right, current]] : [[...left, current], right];
},
[[], []]
);
4 changes: 4 additions & 0 deletions array/range.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default n =>
Array(n)
.fill()
.map((_, index) => index);
1 change: 1 addition & 0 deletions array/repeat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default n => value => Array(n).fill(value);
1 change: 1 addition & 0 deletions array/reverse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default xs => [...xs].reverse();
3 changes: 3 additions & 0 deletions array/reverseIf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import reverse from "./reverse.js";

export default predicate => xs => (predicate ? reverse(xs) : xs);
8 changes: 8 additions & 0 deletions array/rotate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default array => angle => {
const margin = Math.PI / 8;
const angleWithMargin = angle + margin;
const unit = Math.PI / 4;
const ratio = angleWithMargin / unit;
const offset = Math.floor(ratio);
return shift(offset)(array);
};
1 change: 1 addition & 0 deletions array/second.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default ([, x]) => x;
1 change: 1 addition & 0 deletions array/secondToLast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default xs => xs[xs.length - 2];
2 changes: 2 additions & 0 deletions array/shift.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default n => xs =>
xs.map((_, index) => xs[(index + (n % xs.length) + xs.length) % xs.length]);
3 changes: 3 additions & 0 deletions array/shuffle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import shuffleInPlace from "./shuffleInPlace.js";

export default xs => shuffleInPlace([...xs]);
8 changes: 8 additions & 0 deletions array/shuffleInPlace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default xs => {
for (let i = 0; i < xs.length; i++) {
const j = Math.floor(Math.random() * (i + 1));
[xs[i], xs[j]] = [xs[j], xs[i]];
}

return xs;
};
1 change: 1 addition & 0 deletions array/single.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default xs => xs.length === 1;
1 change: 1 addition & 0 deletions array/sort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default f => xs => [...xs].sort(f);
3 changes: 3 additions & 0 deletions array/sum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const add = (a, b) => a + b;

export default xs => xs.reduce(add, 0);
1 change: 1 addition & 0 deletions array/transpose.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default xs => Object.keys(xs[0]).map(key => [xs.map(x => x[key]), key]);
1 change: 1 addition & 0 deletions array/unique.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default xs => [...new Set(xs)];
3 changes: 3 additions & 0 deletions array/zip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import zipWith from "./zipWith.js";

export default zipWith((x, y) => [x, y]);
1 change: 1 addition & 0 deletions array/zipWith.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default f => (xs, ys) => xs.map((x, index) => f(x, ys[index]));
15 changes: 15 additions & 0 deletions async/debounce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default (f, wait) => {
let timeout;

return (...args) => {
const resolve = () => {
timeout = null;

f(...args);
};

clearTimeout(timeout);

timeout = setTimeout(resolve, wait);
};
};
2 changes: 2 additions & 0 deletions async/delay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default duration =>
new Promise(resolve => setTimeout(resolve, duration));
7 changes: 7 additions & 0 deletions async/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import debounce from "./debounce.js";
import delay from "./delay.js";
import sequence from "./sequence.js";

export { debounce, delay, sequence };

export default { debounce, delay, sequence };
14 changes: 14 additions & 0 deletions async/sequence.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default async tasks => {
const results = tasks.map(_ => undefined);

await tasks.reduce((chain, current, i) => {
return chain.then(() =>
current().then(x => {
results[i] = x;
return x;
})
);
}, Promise.resolve());

return results;
};
18 changes: 18 additions & 0 deletions date/byDateWithFallback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export default now => (
{ endedAt: aEnd, startedAt: aStart },
{ endedAt: bEnd, startedAt: bStart }
) => {
const aEndDate = new Date(aEnd || now);
const aStartDate = new Date(aStart || now);
const bEndDate = new Date(bEnd || now);
const bStartDate = new Date(bStart || now);
const aEndDateValue = aEndDate.valueOf();
const aStartDateValue = aStartDate.valueOf();
const bEndDateValue = bEndDate.valueOf();
const bStartDateValue = bStartDate.valueOf();

const startDateDifference = aStartDateValue - bStartDateValue;
const startDatesEqual = startDateDifference === 0;

return startDatesEqual ? aEndDateValue - bEndDateValue : startDateDifference;
};
Loading