我正在计算多对象数组中的元素数量。我该怎么做?
//constructor function
function Bookdes(title, author, pages, current_page, available){
this.title = title;
this.author = author;
this.pages = pages;
this.current_page = current_page;
this.available = available;
}
//array of books
var bookarrays = [
new Bookdes("Fast Cars", "John Burns", 205, 43, "true"),
new Bookdes("Slow Cars", "Joe Fast", 70, 32, "false" ),
new Bookdes("Big Cars", "Darla Jean", 234, 42, "true"),
new Bookdes("Small Cars", "Dema Jones", 214, 34, "false"),
new Bookdes("Cars", "Alex Best", 235, 41, "true")
];
现在我如何计算可用书籍(true)、阅读的页数(current_page)、最长书名的长度?
谢谢
最佳答案
函数式编程技术乍一看似乎有点令人印象深刻,但通常会使此类问题变得更简单。使用Ramda (披露:我是作者之一;但是这些技术在许多其他函数式编程库中都可用)您可以执行以下操作:
var countAvailable = R.pipe(R.filter(R.propEq('available', 'true')), R.prop('length'));
var pagesRead = R.pipe(R.pluck('current_page'), R.sum);
var maxTitleLength = R.pipe(R.pluck('title'), R.pluck('length'), R.max);
每个函数都会返回一个函数,您可以使用 bookarrays
调用该函数。 。您可以在 Ramda REPL 上看到它的实际效果。 .
要点是像pluck
这样的常见函数让您有机会将一个列表更改为另一个列表。所以
pluck('title')(bookarrays);
//=> ["Fast Cars", "Slow Cars", "Big Cars", "Small Cars", "Cars"]
然后您将获得一个更简单的列表以供进一步操作。如果您调用pluck('length')
就可以得到[9. 9, 8, 10, 4]
,然后您可以调用max
关于这一点。所以只需使用 pluck
和max
和pipe
将它们组合在一起,您可以创建一个函数 maxTitleLength
很容易。函数式编程经常这样做:创建可用于相同数据结构(在本例中为列表)的简单可组合函数
更新
这一切的重点不是图书馆本身。这个想法是,如果你制作了许多小的、可重用的、可组合的部件,你就可以用它们构建更复杂的功能。下面是这样一个函数集合的开始,足以解决这些问题:
var add = function(a, b) {
return a + b;
};
var sum = function(list) {
return list.reduce(add, 0);
};
var max = function(list) {
return Math.max.apply(Math, list);
};
var map = function(fn) {
return function(list) {
return list.map(fn);
};
};
var prop = function(name) {
return function(obj) {
return obj[name];
};
};
var pipe = function() {
var funcs = arguments;
return function() {
var args = arguments;
for (var i = 0; i < funcs.length; i++) {
args = [funcs[i].apply(this, args)];
}
return args[0];
};
};
var pluck = pipe(prop, map);
var filter = function(fn) {
return function(list) {
return list.filter(fn);
};
};
var propEq = function(name, val) {
return function(obj) {
return obj[name] === val;
};
}
要使用这个小库,您可以通过组合它们来编写代码。注意 pluck
的定义是多么简单是。
你也可以这样写:
var pluck = function(name) {
return map(prop(name));
};
但是自从 pipe
以这种方式处理组合函数,我们可以简单地编写
var pluck = pipe(prop, map);
显然,使用这些函数,您可以为答案编写函数,如下所示:
var countAvailable = pipe(filter(propEq('available', 'true')), prop('length'));
var pagesRead = pipe(pluck('current_page'), sum);
var maxTitleLength = pipe(pluck('title'), pluck('length'), max);
countAvailable(bookarrays); //=> 3
pagesRead(bookarrays); //=> 192
maxTitleLength(bookarrays); //=> 10
当然,这不是完成此类任务的最简单方法。但现在您可以使用所有这些功能,并且进一步的任务会更容易。这就是函数式编程的意义所在。
<小时/>这跳过了函数式编程中的一个重要工具,称为柯里化(Currying)。有a great article作者:Hugh Jackson 关于这个主题,我写了 another one以及更多详细信息。我不会在这里详细介绍,但这会使这些功能更简单。例如,代替
var propEq = function(name, val) {
return function(obj) {
return obj[name] === val;
};
}
我们可以直接写
var propEq = curry(function(name, val, obj) {
return obj[name] === val;
});
你可以像上面那样调用它,只传递 name
和val
返回一个需要 obj
的函数。或者您可以立即传递所有三个参数:
propEq('length', 3, 'abc'); //=> true
使用 curry
函数将进一步简化上述代码,同时使其更加灵活。
关于javascript - 计算数组中多个对象的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29066590/