Clone wiki

ActionLinq / Home

Logo Sponsored by SRT Solutions

LINQ Extensions for ActionScript 3

See more examples of ActionLinq at RiaRockstars

ActionLinq is a complete implementation of LINQ extensions for ActionScript 3. Although it follows ActionScript idoms, all of the expected functionality is there. Let's start with a simple example of what ActionLinq can do.

Take a handful of numbers, filter them so that only even values appear, square them, rip out duplicates and reverse it.

var transformed:Array =
	[-4, -3, -2, -1, 0, 1, 2, 3, 4]
	.where(isEven)
	.select(square)
	.distinct()
	.reverse()
	.toArray();

assertThat(transformed, array(0, 4, 16));

What is LINQ?

Now that you have seen an example of what LINQ can do, you might be wondering what LINQ is. LINQ is a technology originally developed by Microsoft for querying and transforming data. It stands for "Language-Integrated Query" and in C# there is really some language integration that supports it. Under the hood it has a powerful set of functional methods that allow developers to transform and manipulate data. These methods can be used to work against any data source -- SQL Server, XML, Objects, etc.

So, What is ActionLinq?

ActionLinq is a port of the .Net capabilities for LINQ to Objects (including XML) to ActionScript 3. It is VERY powerful for manipulating data in a functional way. The extensions will work with pretty much any type of collection in ActionScript. Here is an example of pulling out the categories of data so we can display it to a Flex DropDownList. Pull out the category attribute, remove duplicates, order them by string and convert it to an ArrayCollection so it is ready for the UI control as ["Bread", "Cereal", "Meat"].

var xml = <products>
              <product name="Beef"         category="Meat" />
              <product name="Hot Dog Buns" category="Bread" />
              <product name="Bran Flakes"  category="Cereal" />
              <product name="Chicken"      category="Meat" />
              <product name="White Bread"  category="Bread" />
              <product name="Pita Bread"   category="Bread" />
          </products>;

var categories:ArrayCollection =
	Enumerable.from(xml.product)
	.select(function(product):String { return product.@category })
	.distinct()
	.orderBy(identity)
	.toArrayCollection();

// categories is ready for a DropDownList.dataProvider with ["Bread", "Cereal", "Meat"]

ActionLinq can do more complicated data manipulation like joining two sets of unlike data with a common key/foreign key (much like SQL joins):

var customers:Array = [ 
	{id: 1111, name: "John"},
	{id: 2222, name: "Jane" },
	{id: 3333, name: "Jack" }];

var orders:Array = [ 
	{id: 1234, name: "Beef",        customer: 2222 },
	{id: 2345, name: "Bran Flakes", customer: 3333 },
	{id: 3456, name: "Chicken",     customer: 1111 }];

var joined = customers.joinEnumerables(orders.asEnumerable(),
	function(customer)        { return customer.id },
	function(order)           { return order.customer },
	function(customer, order) { return {name: customer.name, product: order.name } });

// returns {name: "John", product: "Chicken"}, {name: "Jane", product: "Beef"}, {name: "Jack", product: "Bran Flakes"}

Using our Fluent Predicate builder, you can re-write the previous join statement:

var joined = customers.joinEnumerables(orders.asEnumerable(),
        element.id,
        element.customer,
        function(customer, order) { return {name: customer.name, product: order.name } });

But That's Not All!

ActionLinq implements ALL of the LINQ extensions. Here is a list of everything available to you. Although there are built-in ASDoc tags for auto-complete help, you can find out more information about these capabilities at the Microsoft site.

where | select | selectMany | take | takeWhile | skip | skipWhile | join | groupJoin | orderBy | orderByDescending | groupBy | concat | zip | distinct | union | intersect | except | reverse | sequenceEqual | toArray | toArrayCollection | toList | toDictionary | toLookup | noneIfEmpty | ofType | cast | first | firstOrNone | last | lastOrNone | single | singleOrNone | elementAt | elementAtOrNone | any | all | count | contains | aggregate | sum | min | max | average | eachElement

More Advanced Topics

Here are some more of the finer details:

Updated