1. lodash中的pick方法

https://lodash.com/docs/4.17.10#pick

_.pick(object, [paths])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var _ = require("lodash");
var objects = [{
"user": "a",
"age": 20,
"name": "aname"
}, {
"user": "b",
"age": 30,
"name": "bname"
}, {
"user": "c",
"age": 40,
"name": "cname"
}];

var results = [];
console.log(objects.filter(function (object) {
var a = _.pick(object, ['user', 'name']);

console.log(a);
results.push(a);
}));
console.log(results);
// =>
// [ { user: 'a', name: 'aname' },
// { user: 'b', name: 'bname' },
// { user: 'c', name: 'cname' } ]

加复杂条件用 _.pickBy()

2. ES6 where筛选

1
2
3
4
5
6
7
8
9
10
var _ = require("underscore");

var json = '[{"user": "a", "age": 20}, {"user": "b", "age": 30}, {"user": "c", "age": 40}]';
var users = JSON.parse(json);
var filtered = _.where(users, {
user: "a"
});

console.log(filtered);
// => [ { user: 'a', age: 20 } ]

https://github.com/lodash/lodash/issues/1247

3. Quickly filter an object by keys

https://codereview.stackexchange.com/questions/79384/quickly-filter-an-object-by-keys

1
2
3
4
5
var matchingKey = myKeys.indexOf(myString) !== -1

var matchingKeys = myKeys.filter(function(key){ return key.indexOf(myString) !== -1 });

var matchingValues = matchingKeys .map(function(key){ return myObject[key] });

4. 自己写的es6方式 解构+合并

destructuring and shorthand object literals

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var objects = [{
"user": "a",
"age": 20,
"name": "aname"
}, {
"user": "b",
"age": 30,
"name": "bname"
}, {
"user": "c",
"age": 40,
"name": "cname"
}];

function jsonfilter(json) {
const { user,name} = json;
return { user,name};
}

var args = [];
objects.map((object) => {
args = args.concat(jsonfilter(object));
});
console.log(args);

You don’t (may not) need Lodash/Underscore

You don’t (may not) need Lodash/Underscore

常用举例
10 Lodash Features You Can Replace with ES6

1. Map, Filter, Reduce

搭配箭头函数

1
2
3
4
5
6
7
8
9
10
11
12
_.map([1, 2, 3], function(n) { return n * 3; });
// [3, 6, 9]
_.reduce([1, 2, 3], function(total, n) { return total + n; }, 0);
// 6
_.filter([1, 2, 3], function(n) { return n <= 2; });
// [1, 2]

// becomes

[1, 2, 3].map(n => n * 3);
[1, 2, 3].reduce((total, n) => total + n);
[1, 2, 3].filter(n => n <= 2);

2. Head & Tail

ES6数组解构获取头尾

1
2
3
4
5
6
7
_.head([1, 2, 3, 4]);
// 1
_.tail([1, 2, 3, 4]);
// [2, 3, 4]

// ES6写法
const [head, ...tail] = [1, 2, 3];
1
2
3
4
5
6
7
8
9
10
11
12
13
_.initial([1, 2, 3]);
// -> [1, 2]
_.last([1, 2, 3]);
// 3

// ES6写法。数组解构和数组reverse反转
const [last, ...initial] = [1, 2, 3].reverse();
//得到initial -> [2, 1]; last -> 3


// ES6写法。不破坏原有数组结构
const xs = [1, 2, 3];
const [last, ...initial] = [...xs].reverse();

3. Rest and Spread

Rest和Spread允许我们定义和调用接受一个可变数量的参数的函数。

https://lodash.com/docs/4.17.10#rest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var say = _.rest(function(what, names) {
var last = _.last(names);
var initial = _.initial(names);
var finalSeparator = (_.size(names) > 1 ? ', & ' : '');
return what + ' ' + initial.join(', ') +
finalSeparator + _.last(names);
});

say('hello', 'fred', 'barney', 'pebbles');
// "hello fred, barney, & pebbles"

// ES6写法
const say = (what, ...names) => {
const [last, ...initial] = names.reverse();
const finalSeparator = (names.length > 1 ? ', &' : '');
return `${what} ${initial.join(', ')} ${finalSeparator} ${last}`;
};

say('hello', 'fred', 'barney', 'pebbles');
// "hello barney, fred, & pebbles"

4. Curry

函数柯里化是指:把接受多个参数的函数转换成接受一个单一参数的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
function add(a, b) {
return a + b;
}
var curriedAdd = _.curry(add);
var add2 = curriedAdd(2);
add2(1);
// 3

// ES6写法
const add = a => b => a + b;
const add2 = add(2);
add2(1);
// 3

方便debug

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var lodashAdd = _.curry(function(a, b) {
return a + b;
});
var add3 = lodashAdd(3);
console.log(add3.length)
// 0
console.log(add3);
// function (a, b) {
// /* [wrapped with _.curry & _.partial] */
// return a + b;
// }

// becomes

const es6Add = a => b => a + b;
const add3 = es6Add(3);
console.log(add3.length);
// 1
console.log(add3);
// function b => a + b

5. Partial

分步输入实参

1
2
3
4
5
6
7
8
9
10
11
12
var greet = function(greeting, name) {
return greeting + ' ' + name;
};

var sayHelloTo = _.partial(greet, 'hello');
sayHelloTo('fred');
// "hello fred"

// ES6写法
const sayHelloTo = name => greet('hello', name);
sayHelloTo('fred');
// "hello fred"

use rest parameters with the spread operator to partially apply variadic functions:

1
2
3
const sayHelloTo = (name, ...args) => greet('hello', name, ...args);
sayHelloTo('fred', 1, 2, 3);
// "hello fred"

6. Operators

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
_.eq(3, 3);
// true
_.add(10, 1);
// 11
_.map([1, 2, 3], function(n) {
return _.multiply(n, 10);
});
// [10, 20, 30]
_.reduce([1, 2, 3], _.add);
// 6

// ES6写法
3 === 3
10 + 1
[1, 2, 3].map(n => n * 10);
[1, 2, 3].reduce((total, n) => total + n);

7. Path

返回Object对象中对应的path路径的值的数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };

_.at(object, ['a[0].b.c', 'a[1]']);
// [3, 4]
_.at(['a', 'b', 'c'], 0, 2);
// ['a', 'c']

// ES6写法
[
obj => obj.a[0].b.c,
obj => obj.a[1]
].map(path => path(object));

[
arr => arr[0],
arr => arr[2]
].map(path => path(['a', 'b', 'c']));

8. Pick

1
2
3
4
5
6
7
8
9
10
var object = { 'a': 1, 'b': '2', 'c': 3 };

return _.pick(object, ['a', 'c']);
// { a: 1, c: 3 }

// becomes

const { a, c } = { a: 1, b: 2, c: 3 };

return { a, c };

9. Constant, Identity, Noop

1
2
3
4
5
6
_.constant({ 'a': 1 })();
// { a: 1 }
_.identity({ user: 'fred' });
// { user: 'fred' }
_.noop();
// undefined

使用箭头函数

1
2
3
4
5
6
7
8
9
10
11
12
13
const constant = x => () => x;
const identity = x => x;
const noop = () => undefined;


=======

(() => ({ a: 1 }))();
// { a: 1 }
(x => x)({ user: 'fred' });
// { user: 'fred' }
(() => undefined)();
// undefined

10. Chaining & Flow

替代链式写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
_([1, 2, 3])
.tap(function(array) {
//改变输入数组.
array.pop();
})
.reverse()
.value();
// [2, 1]

// becomes

const pipeline = [
array => { array.pop(); return array; },
array => array.reverse()
];

pipeline.reduce((xs, f) => f(xs), [1, 2, 3]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const pipe = functions => data => {
return functions.reduce(
(value, func) => func(value),
data
);
};

const pipeline = pipe([
x => x * 2,
x => x / 3,
x => x > 5,
b => !b
]);

pipeline(5);
// true
pipeline(20);
// false