lodash 使用交流 v4.17.4

329上函数 (lodash 上统计的数)

Array: 65

1
["chunk", "compact", "concat", "difference", "differenceBy", "differenceWith", "drop", "dropRight", "dropRightWhile", "dropWhile", "fill", "findIndex", "findLastIndex", "first", "flatten", "flattenDeep", "flattenDepth", "fromPairs", "head", "indexOf", "initial", "intersection", "intersectionBy", "intersectionWith", "join", "last", "lastIndexOf", "nth", "pull", "pullAll", "pullAllBy", "pullAllWith", "pullAt", "remove", "reverse", "slice", "sortedIndex", "sortedIndexBy", "sortedIndexOf", "sortedLastIndex", "sortedLastIndexBy", "sortedLastIndexOf", "sortedUniq", "sortedUniqBy", "tail", "take", "takeRight", "takeRightWhile", "takeWhile", "union", "unionBy", "unionWith", "uniq", "uniqBy", "uniqWith", "unzip", "unzipWith", "without", "xor", "xorBy", "xorWith", "zip", "zipObject", "zipObjectDeep", "zipWith"]

Collection: 28

1
["countBy", "each", "eachRight", "every", "filter", "find", "findLast", "flatMap", "flatMapDeep", "flatMapDepth", "forEach", "forEachRight", "groupBy", "includes", "invokeMap", "keyBy", "map", "orderBy", "partition", "reduce", "reduceRight", "reject", "sample", "sampleSize", "shuffle", "size", "some", "sortBy"]

Date: 1

1
["now"]

Fn: 23

1
["after", "ary", "before", "bind", "bindKey", "curry", "curryRight", "debounce", "defer", "delay", "flip", "memoize", "negate", "once", "overArgs", "partial", "partialRight", "rearg", "rest", "spread", "throttle", "unary", "wrap"]

Lang: 56

1
["castArray", "clone", "cloneDeep", "cloneDeepWith", "cloneWith", "conformsTo", "eq", "gt", "gte", "isArguments", "isArray", "isArrayBuffer", "isArrayLike", "isArrayLikeObject", "isBoolean", "isBuffer", "isDate", "isElement", "isEmpty", "isEqual", "isEqualWith", "isError", "isFinite", "isFunction", "isInteger", "isLength", "isMap", "isMatch", "isMatchWith", "isNaN", "isNative", "isNil", "isNull", "isNumber", "isObject", "isObjectLike", "isPlainObject", "isRegExp", "isSafeInteger", "isSet", "isString", "isSymbol", "isTypedArray", "isUndefined", "isWeakMap", "isWeakSet", "lt", "lte", "toArray", "toFinite", "toInteger", "toLength", "toNumber", "toPlainObject", "toSafeInteger", "toString"]

Math: 15

1
["add", "ceil", "divide", "floor", "max", "maxBy", "mean", "meanBy", "min", "minBy", "multiply", "round", "subtract", "sum", "sumBy"]

Number: 3

1
["clamp", "inRange", "random"]

Object: 47

1
["assign", "assignIn", "assignInWith", "assignWith", "at", "create", "defaults", "defaultsDeep", "entries", "entriesIn", "extend", "extendWith", "findKey", "findLastKey", "forIn", "forInRight", "forOwn", "forOwnRight", "functions", "functionsIn", "get", "has", "hasIn", "invert", "invertBy", "invoke", "keys", "keysIn", "mapKeys", "mapValues", "merge", "mergeWith", "omit", "omitBy", "pick", "pickBy", "result", "set", "setWith", "toPairs", "toPairsIn", "transform", "unset", "update", "updateWith", "values", "valuesIn"]

Seq: 14

1
["at", "chain", "commit", "lodash", "next", "plant", "reverse", "tap", "thru", "toIterator", "toJSON", "value", "valueOf", "wrapperChain"]

String: 31

1
["camelCase", "capitalize", "deburr", "endsWith", "escape", "escapeRegExp", "kebabCase", "lowerCase", "lowerFirst", "pad", "padEnd", "padStart", "parseInt", "repeat", "replace", "snakeCase", "split", "startCase", "startsWith", "template", "templateSettings", "toLower", "toUpper", "trim", "trimEnd", "trimStart", "truncate", "unescape", "upperCase", "upperFirst", "words"]

Util: 32

1
["attempt", "bindAll", "cond", "conforms", "constant", "defaultTo", "flow", "flowRight", "identity", "iteratee", "matches", "matchesProperty", "method", "methodOf", "mixin", "noop", "nthArg", "over", "overEvery", "overSome", "property", "propertyOf", "range", "rangeRight", "stubArray", "stubFalse", "stubObject", "stubString", "stubTrue", "times", "toPath", "uniqueId"]

Properties: 7

Methods: 1

伪码 (lodash中的predicate支持的4种形式)

1
2
3
4
5
6
7
8
9
const users = [
{ 'user': 'barney', 'active': true },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': false }
]

const actived = users.filter(function (user) {
return user.active
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 简写: 只输入一个key
function property (prop) {
return function (obj) {
return obj[prop]
}
}

function myFilter1 (seq, prop) {
return seq.filter(property(prop))
}

const users = [
{ 'user': 'barney', 'active': true },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': false }
]

const myActived = myFilter1(users, "active")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 简写: 可以输入一个数组(第一个值是key, 第二个是value)
function matchesProperty (prop, value) {
return function (obj) {
return obj[prop] === value
}
}

function myFilter2 (seq, values) {
return seq.filter(matchesProperty(values[0], values[1]))
}

const users = [
{ 'user': 'barney', 'active': true },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': false }
]

const fred1 = myFilter2(users, ["user", "fred"])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 简写: 可以输入一个对象(匹配所有的key)
function matches (sources) {
return function (obj) {
return Reflect
.ownKeys(sources)
.every(function (key) {
return obj[key] === sources[key]
})
}
}

const users = [
{ 'user': 'barney', 'active': true },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': false }
]

function myFilter3 (seq, sources) {
return seq.filter(matches(sources))
}

const fred2 = myFilter3(users, {user: "fred"})
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
28
// 综合
function filter (seq, arg) {
if (isFunction(arg)) {
return seq.filter(arg)
}
if (isString(arg)) {
return seq.filter(property(arg))
}
if (isArray(arg)) {
return seq.filter(matchesProperty(values[0], values[1]))
}
if (isPlainObject(arg)) {
return seq.filter(matches(arg))
}
//
throw new Error(...)
}

const users = [
{ 'user': 'barney', 'active': true },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': false }
]

filter(users, {user: "fred", active: true}) // []
filter(users, ["user", "fred"]) // fred
filter(users, "user") // the all
filter(users, user => user.active) // barney

规律

  1. *In (包括prototype)
    forIn, assignIn(extend), toPairsIn, functionsIn, hasIn, keysIn, valuesIn

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function Foo() {
    this.a = 1;
    this.b = 2;
    }

    Foo.prototype.c = 3;

    _.keysIn(new Foo()) // ["a", "b", "c"]
    _.keys(new Foo()) // ["a", "b"]
  2. *Own (忽略prototype)
    forOwn

  3. *Right (从右边开始)
    dropRight, dropRightWhile, takeRight, takeRightWhile, forEachRight, reduceRight, curryRight, partialRight, forInRight, forOwnRight, flowRight, rangeRight

  4. *While (需要 predicate)
    dropRightWhile, dropWhile, takeRightWhile, takeWhile

  5. *Deep (深度xx)
    flattenDeep, zipObjectDeep, flatMapDeep, cloneDeep, cloneDeepWith, defaultsDeep

  6. *Depth (指定深度)
    flattenDepth, flatMapDepth

  7. *By (需要的predicate的参数为1)
    differenceBy, intersectionBy, pullAllBy, sortedIndexBy, sortedLastIndexBy, sortedUniqBy, unionBy, uniqBy, xorBy, countBy, groupBy, keyBy, orderBy, sortBy, maxBy, meanBy, minBy, sumBy, invertBy, omitBy, pickBy

    1
    2
    3
    4
    var objects = [{ 'n': 1 }, { 'n': 2 }];

    _.maxBy(objects, function(o) { return o.n; }); // {n: 2}
    _.maxBy(objects, "n") // ditto
  8. *With (需要的predicate的参数为2)
    differenceWith, intersectionWith, pullAllWith, unionWith, uniqWith, unzipWith, xorWith, zipWith, cloneDeepWith, cloneWith, isEqualWith, isMatchWith, assignInWith, assignWith, mergeWith, setWith, updateWith

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    const components = [
    {
    "id":"51cc2640aa524160bfec9721d7e14e6d",
    "title":"数字输入框",
    },
    {
    "id":"113acd36b33f45b68a6a6a5ee6b17df0",
    "title":"日期",
    },
    {
    "id":"bff3e45c1512450eb49be7284376c8c9",
    "type":"Group",
    "components": [
    {
    "id":"ea7a2c08b3bd44e082eb4468544df2f4",
    "title":"数字输入框1",
    },
    {
    "id":"28288413555a4ce08200497a6b87dcec",
    "title":"开始时间",
    "title2":"结束时间",
    },
    {
    "id":"dc0678f6281a41cea421712220508005",
    "title":"单行输入框",
    },
    {
    "id":"1a5953f3cc61420c91181723d7d4f4b5",
    "title":"图片",
    },
    ],
    }
    ]

    const occupiedComponentsByWorkflows = [
    "28288413555a4ce08200497a6b87dcec",
    "51cc2640aa524160bfec9721d7e14e6d",
    ]

    function isOccupiedByWorkflow (component) {
    return occupiedComponentsByWorkflows.includes(component.id)
    }

    // --- 删除普通组件
    function onRemoveComponent (component) {
    if (isOccupiedByWorkflow(component)) {
    // return
    }
    // ...
    }

    // --- 删除明细组件
    function onRemoveComponent (component) {
    if (isOccupiedByWorkflow(component)) {
    // return
    }

    if (isGroup(component)) {
    const subComponents = component.components
    const occupied = subComponents.some(isOccupiedByWorkflow)

    if (occupied) {
    // return
    }
    }
    // ...
    }

    // ------------------ 如果我们想 找出哪些组件被占用了, 用于alert
    const intersection = _.intersection(
    components,
    occupiedComponentsByWorkflows,
    function (lhs, rhs) {
    return lhs.id === rhs
    },
    )
  9. filter vs reject

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    const users = [
    { 'user': 'barney', 'active': true },
    { 'user': 'fred', 'active': false },
    { 'user': 'pebbles', 'active': false }
    ]

    const onlyActive = _.filter(users, "active")

    const users = [
    { 'user': 'barney', 'age': 5 },
    { 'user': 'fred', 'age': 0 },
    { 'user': 'pebbles', 'age': 42 }
    ]

    const olderThanOneYearOld = _.filter(users, "age")
    const zeroYearOld = _.filter(users, {age: 0})
    const zeroYearOld = _.reject(users, "age")
  10. 函数式编程中常用的函数

    take, compose(flowRight), curry, partial

lodash vs lodash/fp

​ 参数顺序, 不变性

practice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var list = [], virtualList = []

// 分组
$.each(orgList, function(index, item) {
if (item.isInitial == 1) {
if (item.orgId == self.lastSelectedOrgId) { // 副作用 (so bad)
curOrg = item;
}
list.push(item);
} else {
virtualList.push(item)
}
});

// --- alternative

const [list, virtualList] = _.partition(orgList, "isInitial")
const curOrg = _.find(list, {orgId: self.lastSelectedOrgId})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const seq = [
instance1,
instance2,
// ...
]

function resetAll () {
seq.forEach(function (instance) {
instance.reset()
})
}

// ---
function resetAll () {
_.invokeMap(seq, "reset")
}
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
28
29
30
31
32
33
34
35
const components = [
{
"id":"51cc2640aa524160bfec9721d7e14e6d",
"title":"数字输入框",
},
{
"id":"113acd36b33f45b68a6a6a5ee6b17df0",
"title":"日期",
},
{
"id":"bff3e45c1512450eb49be7284376c8c9",
"type":"Group",
"components": [
{
"id":"ea7a2c08b3bd44e082eb4468544df2f4",
"title":"数字输入框1",
},
{
"id":"28288413555a4ce08200497a6b87dcec",
"title":"开始时间",
"title2":"结束时间",
},
{
"id":"dc0678f6281a41cea421712220508005",
"title":"单行输入框",
},
{
"id":"1a5953f3cc61420c91181723d7d4f4b5",
"title":"图片",
},
],
}
]

const flatten = _.flatMap(components, c => c.components ? c.components : c)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var array = [
{ 'dir': 'left', id: "214812384"},
{ 'dir': 'right', id: "999"}
];

_.keyBy(array, "id")

// result
{
"999": {
"dir": "right",
"id": "999",
},
"214812384": {
"dir": "left",
"id": "214812384",
},
}