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 '12 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\$ – DistantEcho Oct 10 '12 at 12:07
  • \$\begingroup\$ Absolutely nothing wrong with that. Just keeping you from rewriting an existing library from scratch. :) \$\endgroup\$ – Neil Oct 10 '12 at 12:11
  • \$\begingroup\$ Why is Collections in plural? It is more common to find constructor names in singular (Array, String, Object). \$\endgroup\$ – Eric Bréchemier Oct 10 '12 at 14:42
  • \$\begingroup\$ @Eric: Good point, I didn't think about that. Neil: thank you then ! \$\endgroup\$ – DistantEcho Oct 10 '12 at 15:08
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\$ – DistantEcho Oct 10 '12 at 15:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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