给出以下(简化)代码,尝试动态计算引导网格:
(function() {
var reduceCalc = _.partial(_.reduce, _, function(memo, entry) {
console.log(entry);
console.log((_.last(memo) + parseInt(entry)));
if (!entry || (parseInt(_.last(memo) + parseInt(entry)) <= 12)) {
_.last(memo).push(entry);
} else {
memo.push([entry]);
}
return memo;
}, [
[]
]);
var oneList = [6, 6];
var twoList = [7, 5, 4, 6];
var rowListOne = reduceCalc(oneList);
var rowListTwo = reduceCalc(twoList);
console.log(rowListOne);
console.log(rowListTwo);
})();
两个问题,
parseInt
是必要的,因为如果没有它,第二个控制台日志:console.log((_.last(memo) + entry));
会将两个整数转换为字符串并返回&#34; 66&#34;,&#34; 75&# 34 ;.为什么这样做?
第二个,也是更重要的问题是:为什么它似乎维持对备忘录的引用,而不是每次运行将其重置为[[]]?最终的控制台日志是:
[Array[0], Array[2], Array[3], Array[1]]
[Array[0], Array[2], Array[3], Array[1]]
为什么要保留这个参考?我怎么能避免这样做呢?在这里演示plunkr:
答案 0 :(得分:2)
让我们先看看这个parseInt
的东西。根本问题是你在memo
中存储了什么样的东西:
memo.push([entry])
因此memo
的条目是单个元素数组,_.last(memo)
是数组。如果你尝试array + something_else
,你最终会将所有内容强制转换为字符串并进行字符串连接,因为或多或少,当JavaScript不知道还能做什么时,一切都会变成字符串化。您想查看memo
内的数组:
console.log(_.last(memo)[0] + entry)
请注意console.log
是可变的,所以你也可以说:
console.log(_.last(memo), entry)
这可能会让您在控制台中看到令人困惑的实时引用,所以这可能会更好:
console.log(_.clone(_.last(memo)), entry)
您的第二个问题是参考问题。你说的是:
var fn = function(memo,entry) { ... };
var aoa = [ [ ] ];
var reduceCalc = _.partial(_.reduce, _, fn, aoa);
aoa
数组将隐藏在reduceCalc
内,并且每次调用reduceCalc
时都会使用该数组。您的代码中没有任何内容可以为每次调用创建一个新数组。
如果你想要一个新阵列,那么你需要做这样的事情:
var reduceCalc = _.partial(_.reduce, _, function(memo, entry) {
memo = memo || [ [ ] ]; // Create a new array specific to this invocation
//...
return memo;
}, null);
首次调用回调时,null
需要_.reduce
来null
memo
_.reduce
值,memo
将会使用{{1}}如果你没有指定一个明确的参数,那么它的第一个条目作为初始{{1}}。