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

时间:2015-03-15 21:50:39

标签: 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")
];

现在我如何计算可用的书籍(真实),阅读的页面总数(current_page),最长标题的长度?

谢谢,

3 个答案:

答案 0 :(得分:3)

功能性编程技术,起初看起来有点强调,通常会使问题变得更简单。使用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。因此,只需将pluckmax以及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 。休·杰克逊(Hugh Jackson)关于这个主题的a great article,我写了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函数可以进一步简化上述代码,同时使其更加灵活。

答案 1 :(得分:0)

检查此fiddle以获取实时演示

//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")
];

function sum(){
   var i;
    var count = 0;
    var maxlen = 0;
    var read = 0;
    for(i=0; i<bookarrays.length; i++){
        if(bookarrays[i].title.length > maxlen){
             maxlen = bookarrays[i].title.length;
        }
        if(bookarrays[i].available === "true" || bookarrays[i].available === true){
             count++;   
        }
        read += bookarrays[i].current_page;

    }
    $("#out").html("Count: " + count + "<br>Maxlength: " + maxlen + "<br>read: " + read);
}

$(function(){
       sum();
});

还有一点HTML:

<div id="out"></div>

打印:

Count: 3
Maxlength: 10
read: 192

只需遍历每个元素并执行您想要的操作

答案 2 :(得分:0)

Live Demo

//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 === 'true';
}
//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")
];

var available = 0;
var page = 0;
var longest = '';

for (var i = 0, max = bookarrays.length; i < max; i += 1) {
    bookarrays[i].available && (available += 1);
    page += bookarrays[i].current_page;
    longest = bookarrays[i].title.length > longest.length ? bookarrays[i].title : longest;
}

alert(available);
alert(page);
alert(longest);