Ext JS has a number of handy iterator functions. Some, like Ext.each, you probably already know about, but there are a few others lurking around which can be useful in saving yourself a few lines of code. First, let's recap Ext.each:
Ext.each
Ext.each applies a function to each member of an array. It's basically a more convenient form of a for loop:
var people = ['Bill', 'Saul', 'Gaius'];
//using each to detect Cylons:
Ext.each(people, function(person, index) {
var cylon = (index + 1) % 2 == 0; //every second man is a toaster
alert(person + (cylon ? ' is ' : ' is not ') + 'a fraking cylon');
});
//is the same as
for (var i=0; i < people.length; i++) {
var person = people[i];
var cylon = (i + 1) % 2 == 0; //every second man is a toaster
alert(person + (cylon ? ' is ' : ' is not ') + 'a frakin cylon');
};
var people = ['Bill', 'Saul', 'Gaius'];
//using each to detect Cylons:
Ext.each(people, function(person, index) {
var cylon = (index + 1) % 2 == 0; //every second man is a toaster
alert(person + (cylon ? ' is ' : ' is not ') + 'a fraking cylon');
});
//is the same as
for (var i=0; i < people.length; i++) {
var person = people[i];
var cylon = (i + 1) % 2 == 0; //every second man is a toaster
alert(person + (cylon ? ' is ' : ' is not ') + 'a frakin cylon');
};
Ext.iterate
Ext.iterate is like Ext.each for non-array objects. Use it wherever you would normally use a for .. in loop:
var ships = {'Bill': 'Galactica', 'Laura': 'Colonial One'};
Ext.iterate(ships, function(key, value) {
alert(key + "'s ship is the " + value);
});
//is the same as
for (key in ships) {
var value = ships[key];
alert(key + "'s ship is the " + value);
}
var ships = {'Bill': 'Galactica', 'Laura': 'Colonial One'};
Ext.iterate(ships, function(key, value) {
alert(key + "'s ship is the " + value);
});
//is the same as
for (key in ships) {
var value = ships[key];
alert(key + "'s ship is the " + value);
}
Using Ext.iterate with an array is the same as calling Ext.each. Each and Iterate both take an optional third parameter, which is the scope to run the function in. Another advantage over using the for construct is that you can easily reuse the same function:
var myFunction = function(item, index) {
//does some clever thing
}
Ext.each(people, myFunction);
Ext.each(['another', 'array'], myFunction);
var myFunction = function(item, index) {
//does some clever thing
}
Ext.each(people, myFunction);
Ext.each(['another', 'array'], myFunction);
Ext.pluck
Ext.pluck grabs the specified property from an array of objects:
var animals = [
{name: 'Ed', species: 'Unknown'},
{name: 'Bumble', species: 'Cat'},
{name: 'Triumph', species: 'Insult Dog'}
];
Ext.pluck(animals, 'species'); //returns ['Unknown', 'Cat', 'Insult Dog']
Ext.pluck(animals, 'name'); //returns ['Ed', 'Bumble', 'Triumph']
var animals = [
{name: 'Ed', species: 'Unknown'},
{name: 'Bumble', species: 'Cat'},
{name: 'Triumph', species: 'Insult Dog'}
];
Ext.pluck(animals, 'species'); //returns ['Unknown', 'Cat', 'Insult Dog']
Ext.pluck(animals, 'name'); //returns ['Ed', 'Bumble', 'Triumph']
Ext.invoke
Invoke allows a function to be applied to all members of an array, and returns the results. Using our animals object from above:
var describeAnimal = function(animal) {
return String.format("{0} is a {1}", animal.name, animal.species);
}
var describedAnimals = Ext.invoke(animals, describeAnimal);
console.log(describedAnimals); // ['Ed is a Unknown', 'Bumble is a Cat', 'Triumph is a Insult Dog'];
var describeAnimal = function(animal) {
return String.format("{0} is a {1}", animal.name, animal.species);
}
var describedAnimals = Ext.invoke(animals, describeAnimal);
console.log(describedAnimals); // ['Ed is a Unknown', 'Bumble is a Cat', 'Triumph is a Insult Dog'];
Ext.invoke performs a similar job to Ruby's collect method in making it easy to transform arrays. Any additional arguments passed to the Ext.invoke call will be passed as arguments to your function, in this case the describeAnimal function. Obviously your functions will be much more grammatically accurate than mine.
Ext.partition
Ext.Partition splits an array into two sets based on a function you provide:
var trees = [
{name: 'Oak', height: 20},
{name: 'Willow', height: 10},
{name: 'Cactus', height: 5}
];
var isTall = function(tree) {return tree.height > 15};
Ext.partition(trees, isTall);
//returns:
[
[{name: 'Oak', height: 20}],
[{name: 'Willow', height: 10}, {name: 'Cactus', height: 5}]
]
var trees = [
{name: 'Oak', height: 20},
{name: 'Willow', height: 10},
{name: 'Cactus', height: 5}
];
var isTall = function(tree) {return tree.height > 15};
Ext.partition(trees, isTall);
//returns:
[
[{name: 'Oak', height: 20}],
[{name: 'Willow', height: 10}, {name: 'Cactus', height: 5}]
]
The partition call above returns a 2-dimensional array with the first element containing all of the items for which the function returned true (tall trees in this case), and the second containing items for which the function return false.
Math functions
Finally, we have some simple math-related functions:
var numbers = [1, 2, 3, 4, 5];
Ext.min(numbers); //1
Ext.max(numbers); //5
Ext.sum(numbers); //15
Ext.mean(numbers); //3
var numbers = [1, 2, 3, 4, 5];
Ext.min(numbers); //1
Ext.max(numbers); //5
Ext.sum(numbers); //15
Ext.mean(numbers); //3
While the built in functions don't cater for all situations, they're useful to have and to know about, and usually offer a more elegant approach than using the 'for' keyword.