tjmehta / 101 Goto Github PK
View Code? Open in Web Editor NEWA modern JS utility library
License: MIT License
A modern JS utility library
License: MIT License
omit
currently clone
s the source object and then deletes "omitted" properties from the copy.
In the scenario that omitted properties are very large, clone is unnecessarily copying a large amount of data and immediately deleting
it.
Reimplement omit
to avoid copying "omitted" properties.
First, I know this is against one of the philosophies of 101. But as the library grows it would sometimes be nice if one could install only what he needs. i.e npm i 101-curry
. We could create a cli-tool to publish only changed function and keep developing 101 in one repo.
What are your thoughts on this?
Yes, yes, the native Function.prototype.bind
method is solid, but there are situations where the Underscore bindAll
method is just what you need.
I propose to extract the bindAll method from the Underscore library, remove the support for when the ES5 bind
is not available and call it a day.
If there is enough interest, I can create a PR
Hi! Very nice lib, I like the way it is included.
Im't thinking to replace mutype with 101 in all depending projects, but 101 still lacks of some, I believe, useful checks:
has(obj, property)
— a faster check than .hasOwnProperty
(http://jsperf.com/hasownproperty-vs-in-vs-undefined/12).isNumber
— to avoid typeof a === 'number'
(useful for closurecompiler).isPlain
— !arg || isBoolean(arg) || isNumber(arg) || isString(arg)
— very often needed to exclude non-objects.isArrayLike
/ isList
— to check anything which looks like an ordered collection Array, NodeList, Collection, or anything with numeric length but not string, window, form, function.isArray
, isRegExp
isEmpty
— whether object is empty.var obj = {foo:1, bar:2, baz:3, yolo:4}
pluck(obj, 'foo', 'bar', 'baz') -> {foo:1, bar:2, baz:3}
Pretty crazy issue. My npm outdated
started failing... After some tracing I noticed that 101
causes a weird run in the dependency array built in the npm outdated
utility. I'm guessing this is a npm bug related to the numeric module name (tests with "202" and "2" showed the same result).
Documenting here, in case you want to raise an issue with the npm team. A brief search makes me think this hasn't been filed yet.
Steps to reproduce:
devDependencies
object in package.jsonnpm outdated
npm ERR! Darwin 15.0.0
npm ERR! argv "/usr/local/Cellar/node/4.2.1/bin/node" "/Users/mshick/.node/bin/npm" "outdated"
npm ERR! node v4.2.1
npm ERR! npm v3.3.6
npm ERR! Cannot read property 'name' of undefined
Here's a sample npm-debug.log entry:
0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/Cellar/node/4.2.1/bin/node',
1 verbose cli '/Users/mshick/.node/bin/npm',
1 verbose cli 'outdated' ]
2 info using [email protected]
3 info using [email protected]
4 silly mapToRegistry name MD5
5 silly mapToRegistry using default registry
6 silly mapToRegistry registry https://registry.npmjs.org/
7 silly mapToRegistry uri https://registry.npmjs.org/MD5
8 silly mapToRegistry name adm-zip
9 silly mapToRegistry using default registry
10 silly mapToRegistry registry https://registry.npmjs.org/
11 silly mapToRegistry uri https://registry.npmjs.org/adm-zip
12 verbose stack TypeError: Cannot read property 'name' of undefined
12 verbose stack at /Users/mshick/.node/lib/node_modules/npm/lib/outdated.js:295:27
12 verbose stack at /Users/mshick/.node/lib/node_modules/npm/node_modules/slide/lib/async-map.js:52:35
12 verbose stack at Array.forEach (native)
12 verbose stack at /Users/mshick/.node/lib/node_modules/npm/node_modules/slide/lib/async-map.js:52:11
12 verbose stack at Array.forEach (native)
12 verbose stack at asyncMap (/Users/mshick/.node/lib/node_modules/npm/node_modules/slide/lib/async-map.js:51:8)
12 verbose stack at outdated_ (/Users/mshick/.node/lib/node_modules/npm/lib/outdated.js:294:3)
12 verbose stack at /Users/mshick/.node/lib/node_modules/npm/lib/outdated.js:78:5
12 verbose stack at /Users/mshick/.node/lib/node_modules/npm/lib/install/deps.js:119:5
12 verbose stack at LOOP (/Users/mshick/.node/lib/node_modules/npm/node_modules/slide/lib/chain.js:7:26)
13 verbose cwd /Users/mshick/code/project
14 error Darwin 15.0.0
15 error argv "/usr/local/Cellar/node/4.2.1/bin/node" "/Users/mshick/.node/bin/npm" "outdated"
16 error node v4.2.1
17 error npm v3.3.6
18 error Cannot read property 'name' of undefined
19 error If you need help, you may report this error at:
19 error <https://github.com/npm/npm/issues>
20 verbose exit [ 1, true ]
var opts = {}
defaults(opts, {
'foo.bar': 'hai'
})
console.log(opts.foo.bar) // "hai"
One use case:
[ {a: true, b: false}
, {a: false, b: false}
, {a: true, b: true}
].filter(compose(and
, [ pluck("a")
, pluck("b")
]
));
// » [{a: true, b: true}]
Underscore/lodash is large, and you have to manually create custom builds when if you're trying to optimize for size.
That's not entirely accurate. Underscore doesn't support custom builds and Lo-Dash provides module bundles for AMD & Node as well as npm packages.
Lo-Dash 3.0 will also officially support ES6 modules as well as paths such as require('lodash/object/clone')
out of the box 😀
I've been reading issue #16 (closed now), and just wanted to bump the idea of having a flip()
function.
The original proposition by @jfsiii:
flip
(orreverseArguments
, etc)function flip(fn) { return function() { var args = [].slice.call(arguments).reverse(); return fn.apply(this, args); }; }It might seem silly to have a function which just reverses argument order, but it's a great help when you want to invoke a existing function which does what you want/need but has arguments in the opposite order.
In addition to the arguments posted already, I see one great use case – currying right-hand-side arguments.
In the JS world this is common: doGreatStuff(target, options)
. A function with optional arguments or an options
object listed on the very right.
I often want to .bind()
the optional arguments. Wouldn't it be great to do flip(doGreatStuff).bind(null, {candyFloss: true})
?
As of [email protected]:
set({a: {b: "c"}}
, "a.b", "d"
);
// » {a: {b: "c"}, "a.b": "d"}
Maybe that's intended – but the docs say:
// supports keypaths by default
methods that use clone
can cause it to throw errors.
these error message are not developer friendly (stack traces pointing to clone
code)
throw more better errors in these scenarios so that the error can be trace to the 101 method being used.
It's another idea than #38. Author in ES6, transpile to a universal module format for node, AMD and the browser.
The original idea came from Ryan Florence some time ago. I've followed his advice in tomekwi/as.js. The technology is still quite rough, but everything seems work smoothly.
The readme for set
says:
returns a new obj with the key and value set
I'd seen it as a powerful functionality which allowed me to get immutability in JS without using an obese library.
– until I noticed that it's the original object that gets changed and returned after all.
Is it supposed to be so?
Maybe we can use this out to start (for the versions we've missed):
last(arr, key, val)
This is a bug I came across in a project.
I implemented my own .last()
method, then. I realized the problem is, using Object.keys()
method returns different array for different browser. Generally browsers tend to return the order as the indexes inserted by it's better not to trust it.
Maybe it's better to sort alphabetically and return the last result here
Detailed explanation is on stackoverflow
Basically a polyfil for https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
arr.sort(sortBy('key.path')) or arr.sort(sortBy('-key.path'))
remove([1,2,3], 1)
remove([1,2,3], equals(1))
I didnt see any manifesto about supportting or not supporting older platforms, are theese functions will/can be in 101?
put(obj, 'foo.bar.qux', true)
var maxOf2 = curry(Math.max, 2);
maxOf2(10, 20, [1,2,3]); // should return 20, but currently returns NaN
With #87 101 will have a first
function which often comes with a tail
function.
tail([1, 2, 3, 4]);
// => [2, 3, 4]
tail('_hello');
// => 'hello'
🌻
Should it work with reduce?
[
{ foo: 'bar', bar: 'yo' },
{ foo: 'bar' },
{ foo: 'flux' },
{ foo: 'flux', qux: 100 }
].reduce(groupBy('foo'), {});
/* returns
{
'bar': [
{ foo: 'bar', bar: 'yo' },
{ foo: 'bar' }
],
'flux': [
{ foo: 'flux' },
{ foo: 'flux', qux: 100 }
]
}
*/
Note: It requires an initial value which makes it a less "plug and play".
Or just
groupBy(arr, 'foo')
As the jsdoc of or
states, or
should return a boolean.
/**
* Functional version of ||
* @function module:101/and
* @param {*} a - any value
* @param {*} b - any value
* @return {boolean} a || b
*/
But it returns the value passed to the function, if it is thruthy.
var or = require('./or');
or(1, false);
// => 1
or("101", false);
// => "101"
I have a PR ready if you want to change this behaviour.
It's be awesome if compose
took an unlimited amount of arguments. Is there a reason this is not the case? (Could help out with a PR if no one objects) @tjmehta
$ node
> var compose = require('101/compose')
undefined
> var plusOne = (x) => x + 1
undefined
> compose(plusOne, plusOne, plusOne)(1)
3
> compose(plusOne, plusOne, plusOne, plusOne)(1)
3
The examples for apply
mention and
.
The examples for equals
mention exists
.
This isn't an issue, just a question:
@tjmehta Is there any reason you're returning module exports like this?
module.exports = and;
function and (a, b) {
return a && b;
}
Why not this?
module.exports = function(a, b) {
return a && b;
}
or this?
function and (a, b) {
return a && b;
}
module.exports = and;
or this?
var and = function (a, b) {
return a && b;
}
module.exports = and;
or this?
module.exports = and;
var and = function (a, b) {
return a && b;
}
I'm not trying to sound snobby or anything. I know people have many different preferred ways of doing things. I was just wondering if there was a specific reason for doing so. It seems weird to use the function before it's called. I'm very curious! Thanks!
Is it possible to bend set
to set properties through a function? I mean like:
var markdown = require("marked");
[{string: "..."}, {string: "..."}].map(compose
( set("html", markdown)
, pluck("string")
));
includes([1,2,3,4], 1) // true
var notIn = not(includes);
[1,2,3,4,5].filter(notIn([1,2,3])) // [4,5]
thoughts: accept an object that takes keypaths and regexp values too.
"test": "./node_modules/.bin/lab -c test"
That way one can simply npm install
to run the tests
101/defaults currently both mutates it's target
argument and returns the mutated target
argument. This isn't shown in the documentation. https://github.com/tjmehta/101#defaults
It should either:
target
, extend target
, and return target
target
and return undefined (or maybe return a boolean indicating if defaults were applied or not)Mutating the argument and returning it is redundant.
Edit:
Came across this use of defaults in our code:
// unnecessary to assign return value to opts, implementor was unaware defaults mutates and returns
opts = defaults(opts, { foo: 'bar' });
Should it work with reduce?
[
{ foo: 'bar', bar: 'yo' },
{ foo: 'qux' },
{ foo: 'flux' },
{ foo: 100 }
].reduce(indexBy('foo'), {});
/* returns
{
'bar': { foo: 'bar', bar: 'yo' },
'foo': { foo: 'qux' },
'flux': { foo: 'flux' },
'100': { foo: 100 }
}
*/
Note: It requires an initial value which makes it a less "plug and play".
Or just
indexBy(arr, 'foo')
There is no index.js
file, but the package.json
file references it as main
.
const obj = {
foo: undefined,
bar: false,
qux: true
}
pick(obj, ['foo', 'bar', 'yolo'])
/*
{
bar: false
}
should return:
{
foo: undefined,
bar: false
}
*/
to get unique values in an array
arr.reduce
equals
arg?You've reached a conclusion in #17, that AMD is fairly compatible with CommonJS – you can use one within the other or transpile one to the other. That's not the case with ES6 modules. They are designed to be statically analysable (without executing the code) – so there are things impossible to transpile. Such as:
if (hasToGo) require('car').driveHome();
// ...or:
module.exports = something || somethingElse;
Looking by the simplicity of your modules, it should be easy to copy each file to 101/es6/
, replacing:
module.exports = a;
with export default a;
, andvar b = require('./b');
with import b from './b';
.I've had a very rough go at this, because I needed two modules in an ES6 project. A simple search-and-replace did it in my case: tomekwi/101-es6.
The problem is dependency on CommonJS modules (clone, keypather and deep-eql – we should be able to replace extend with 101/assign).
Possible solutions:
import clone from 'clone';
). Some compilers (6to5) can handle this as a temporary ES5-ES6 brigde.Great library. "compose" would be good. Maybe "pipe" too so that you send values through a series of functions.
Functional programming has always liked arrays. But objects are no less powerful, especially in the everything-is-an-object world of JavaScript.
I've been using these two a lot lately. What do you think?
var arr = [
{
one: 'foo',
two: 'bar'
},
{
one: 'qux',
two: 'zoo'
}
]
indexBy(arr, 'one', 'foo')
indexBy(arr, pluck('one'), pluck('two'))
/*
{
foo: 'bar',
qux: 'zoo'
}
*/
Currently a composed function takes only one argument:
function compose(f,g) {
return function composed(x) {
return f(g(x));
}
With this implementation you can't do this:
var add = function(a, b) { return a+b; };
var sqr = function(a) { return a*a; };
var composed = compose(sqr, add);
composed(1, 2);
// expected => 9
// actual => NaN
How about we change compose to create a function which passes all arguments to the first function:
function compose(f,g) {
return function composed(/* args */) {
var args = Array.prototype.slice.call(arguments);
return f(g.apply(null, args));
}
Checkout my implementation of compose
it passes all arguments to the first function (https://github.com/stoeffel/compose-function)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.