代码之家  ›  专栏  ›  技术社区  ›  Bigboy6

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

  •  0
  • Bigboy6  · 技术社区  · 9 年前

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

    //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)和最长标题的长度?

    谢谢

    3 回复  |  直到 9 年前
        1
  •  3
  •   Scott Sauyet    9 年前

    函数式编程技术一开始可能看起来有点令人印象深刻,但通常会使此类问题变得更简单。使用 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 在这方面。所以只要使用 最大值 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;
      };
    }
    

    要使用这个小库,您可以通过组合它们来编写代码。注意

    你也可以这样写:

    var pluck = function(name) {
      return map(prop(name));
    };
    

    但从那时起 以这种方式处理组合函数,我们可以简单地编写

    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
    

    当然,这不是完成此类任务的最简单方法。但现在您已经拥有了所有这些功能,进一步的任务将更容易。这就是函数式编程的意义所在。


    这跳过了函数式编程中的一个重要工具 咖喱 。有 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 函数将进一步简化上述代码,同时使其更加灵活。

        2
  •  0
  •   Boris Zagoruiko    9 年前

    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);
    
        3
  •  0
  •   balping    9 年前

    检查此项 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
    

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