4
\$\begingroup\$

As I was working with .NET, I started wondering how I would implement the LINQ methods syntax in Javascript. So here is my first try; is there a more elegant, or more performant, way to write this code?

// usage : the functions take a predicate function as input and modify the array accordingly 
var collection;
(function() {
    "use strict";

    var Collections = function(array) {
        this.array = array;
    };

    Collections.prototype = {
        //The predicate should return a boolean value
        //Keeps all elements that match the given function
        where: function(predicate) {
            var newArray = [];
            this.each(function(index, item) {
                if (predicate(item)) {
                    newArray.push(item);
                }
            });
            this.array = newArray;
            return this;
        },
        //The predicate should return a boolean value
        //Returns true if one element or more matches the predicate
        any: function(predicate) {
            var newArray = [];
            this.each(function(index, item) {
                if (predicate(item)) {
                    newArray.push(item);
                }
            });
            return newArray.length > 0;
        },
        //The predicate should return an object
        //Replaces all elements by the object generated by the predicate
        select: function(predicate) {
            var newArray = [];
            this.each(function(index, item) {
                newArray.push(predicate(item));
            });
            this.array = newArray;
            return this;
        },
        //Returns the current (modified) array
        getArray: function() {
            return this.array;
        }
    };

    collection = function(array) {
        return new Collections(array);
    };
} ());

And here is an exemple of use:

var myArray = [{name: 'chicken', size: 1}, {name: 'cat', size: 2}, 
{name: 'dog', size: 3}, {name: 'horse', size: 4}, {name: 'skunk', size: 2}];
var newArray = collection(myArray)
    .where(function(animal){
        return animal.size == 2
    })
    .select(function(animal){
        return {
            animalName: animal.name,
            category: 'mammal',
            size: 'small'
        }
    })
    .getArray()
// new array : [{animalName: 'cat', category: 'mammal', size: 'small}, {animalName: 'skunk', 
// category: 'mammal', size: 'small'}]
\$\endgroup\$
5
  • \$\begingroup\$ So you're rewriting underscore.js? \$\endgroup\$
    – Neil
    Oct 10, 2012 at 11:55
  • \$\begingroup\$ Not the whole library obviously. I just wanted to work on something small to experiment with the code and try to improve my code style. \$\endgroup\$ Oct 10, 2012 at 12:07
  • \$\begingroup\$ Absolutely nothing wrong with that. Just keeping you from rewriting an existing library from scratch. :) \$\endgroup\$
    – Neil
    Oct 10, 2012 at 12:11
  • \$\begingroup\$ Why is Collections in plural? It is more common to find constructor names in singular (Array, String, Object). \$\endgroup\$ Oct 10, 2012 at 14:42
  • \$\begingroup\$ @Eric: Good point, I didn't think about that. Neil: thank you then ! \$\endgroup\$ Oct 10, 2012 at 15:08

1 Answer 1

2
\$\begingroup\$

To clarify the use of your global variable "collection" as a namespace for your library, you should assign it directly to a value returned by your Immediately Invoked Function Expression:

var collection = (function(){
  ...

  function collection(array) {
    return new Collections(array);
  }

  return collection;
}());
\$\endgroup\$
1
  • \$\begingroup\$ Alright, it does seem clearer that way. \$\endgroup\$ Oct 10, 2012 at 15:08

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.