Почему обертка Lodash не работает с forEach? - PullRequest
1 голос
/ 04 октября 2019

Я сталкивался с этим при обновлении цепочек манипуляций с lodash, и я не понимаю, почему это будет работать по-другому

Я сузил его до создания цепочки forEach на оболочке lodash

let tab = [{a:1, b:1}, {a:1, b:2}, {a:2, b:1},{a:2, b:2}]
let res = _(tab).forEach(el => {el.c = 3; return el;}).groupBy('a')
console.log(res)

https://jsbin.com/wahokezeja/edit?js,console

Это приведет к ошибке:

"Ошибка типа: _ (...). ForEach (...). GroupBy не является функцией

Однако при объединении с картой все работает нормально

let tab = [{a:1, b:1}, {a:1, b:2}, {a:2, b:1},{a:2, b:2}]
let res = _(tab).map(el => {el.c = 3; return el;}).groupBy('a').value()
console.log(res)

https://jsbin.com/mofusel/1/edit?js,console

Это как-то связано с _ (tab) .forEach возвращает массив, а неОболочка Лодаша, но не понимаю, почему это происходит.

1 Ответ

3 голосов
/ 04 октября 2019

Lodash forEach не ведет себя точно так же, как JS forEach, но и не совсем как карта. _.map([1,2,3],a=>2*a) вернет массив [2,4,6], как и следовало ожидать, однако _.forEach([1,2,3],a=>a*2) вернет [1,2,3]. Он предназначен для выполнения операции для каждого элемента массива (например, JS [].forEach), но он не возвращает модифицированный массив, а для удобства возвращает массив original . Если вы хотите изменить массив, используйте map.

Попробуйте следующее:

var arr=[1,2,3]; 
var rslt=_(arr).forEach(v=>v*2); 
console.log(arr===rslt);

и вы увидите, что он возвращает true - «результат» из forEach, обернутыйили нет, это просто исходный массив.

После поиска в коде lodash и некоторых полезных комментариев от @VLAZ ключом к пониманию является ленивая оценка, связанная с цепочкой (которая является точкойОбтекание массива, указанное выше). (Обернутые) цепочечные методы обеспечивают ленивую оценку. Если вы вызываете _(array).map(fn1).map(fn2).value(), то оценка не будет выполнена, пока не будет вызван метод значения. Это хорошее улучшение эффективности, так как (в данном случае) генерируется только один выходной массив (в отличие от стандартного метода JS map, промежуточные массивы будут генерироваться после каждого шага). Однако forEach отличается - он требует немедленного выполнения и поэтому завершает цепочку.

...