0

I am looking to count elements in the multi object array. How would I do this?

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

Now how do I Count books available (true), sum of pages read (current_page), length of longest title?

Thanks,

3
  • 2
    Is this a homework assignment? And have you tried anything? Commented Mar 15, 2015 at 21:59
  • What have you tried? I'm not sure what you're trying to count. bookarrays.length will give you the elements in the array. Commented Mar 15, 2015 at 21:59
  • 1
    Why do you use a string for the available parameter instead of just the boolean true or false values? Commented Mar 15, 2015 at 22:06

3 Answers 3

3

Functional programming techniques, which may seem a little imposing at first, often make problems like this simpler. Using Ramda (disclosure: I'm one of the authors; but these techniques are available in many other functional programming libraries) you can do things like this:

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);

Each of these returns a function which you can call with bookarrays. You can see it in action on the Ramda REPL.

The main point is that a common function like pluck gives you the chance to change one list into another. So

pluck('title')(bookarrays);
//=> ["Fast Cars", "Slow Cars", "Big Cars", "Small Cars", "Cars"]

Then you have a simpler list for further manipulation. If you call pluck('length') on that you get [9. 9, 8, 10, 4], and then you can call max on that. So just using pluck and max and pipeing them together, you can create a function maxTitleLength quite easily. Functional programming does this a lot: creating simple composable functions that can be used on the same data structures (in this case, lists)


Update

The point of all this is not the library itself. The idea is that if you make a number of small, reusable, composable pieces, you can build up your more complex functions out of them. Here is the beginning of such a collection of functions, enough to solve those problems:

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;
  };
}

To use this little library, you can then write your code by combining them. Note how simple the definition of pluck is.

You could also write it as this:

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

But since pipe handles combining functions in that way, we can simply write

var pluck = pipe(prop, map);

Obviously, using these functions, you can then write functions for your answers like this:

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

Of course this is not the easiest way to complete a task like this. But now you have all those functions available, and further tasks would be easier. That's what functional programming is about.


This skips one important tool in functional programming, called currying. There's a great article by Hugh Jackson on the topic, and I wrote another one with additional details. I won't go into details here, but it would make those functions simpler. For instance, instead of

var propEq = function(name, val) {
  return function(obj) {
    return obj[name] === val;
  };
}

we could just write

var propEq = curry(function(name, val, obj) {
  return obj[name] === val;
});

and you could call it as above, passing only name and val to get back a function that takes obj. Or you could pass it all three parameters right away:

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

Using a curry function would simplify the above code quite a bit further and simultaneously make it more flexible.

Sign up to request clarification or add additional context in comments.

2 Comments

I wish I could use tools like these except I am still learning about libraries and all what they can do.
@Bigboy6: Updated to show how to build such tools out of simpler ones.
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);

2 Comments

Wow very helpful! So I am new to Javascript and am still getting a hang on this. When I tried to search for help I could only find info on arrays with single properties and none with an array of objects with multiple elements. So what does the "?" in the last line of the for loop, and what do this do?
0

Check this fiddle for 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;
}
//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();
});

And a little HTML:

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

It prints:

Count: 3
Maxlength: 10
read: 192

Just loop through each element and do what you want

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.