javascript - 计算数组中多个对象的属性

标签 javascript arrays for-loop javascript-objects

我正在计算多对象数组中的元素数量。我该怎么做?

//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关于这一点。所以只需使用 pluckmaxpipe将它们组合在一起,您可以创建一个函数 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;
});

你可以像上面那样调用它,只传递 nameval返回一个需要 obj 的函数。或者您可以立即传递所有三个参数:

propEq('length', 3, 'abc'); //=> true

使用 curry函数将进一步简化上述代码,同时使其更加灵活。

关于javascript - 计算数组中多个对象的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29066590/

相关文章:

javascript - 如何遍历包含小于迭代器值的数组

javascript - jquery从脚本中获取变量

java - Java 数组快速排序中的堆栈溢出

javascript - 如果选中单选按钮,如何按值隐藏元素?

arrays - golang 中的变量 getter 函数

java - 在 AWT (Java) 中排序和显示数组的问题

java - 设置增强for循环的初始值

python - 在具有不同数组形状的 Python/Numpy 中向量化三重 for 循环

javascript - 防止 ajax 提交空白输入和选择

javascript - TypeError,captureStream 不是函数