/*

Array.every(function)

DESCRIPTION

The every method is a Firefox method which accepts a function as an argument. 
Every value of the array is passed to that function until the function returns false. 
If no elements return false then every will return true, 
if an element returned false then every will return false. 
It's a convenient way to test an Array and see if every element is a number for instance.
This method will pass the current value, the current index, and a pointer to the array to your function. 
myfunction(curValue, curIndex, curArray) 

EXAMPLE

var isNumeric = function(x) {
   // returns true if x is numeric and false if it is not.
   var RegExp = /^(-)?(\d*)(\.?)(\d*)$/; 
   return String(x).match(RegExp);
}
var myArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
document.writeln(myArray.every(isNumeric));   // outputs: true
var myArray = [1,2,3,4,5,6,7,8,9,'ten',11,12,13,14,15];
document.writeln(myArray.every(isNumeric));   // outputs: false

*/

if (!Array.prototype.every)
{
  Array.prototype.every = function(fun)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          !fun.call(thisp, this[i], i, this))
        return false;
    }

    return true;
  };
}

/*

Array.filter(function)

DESCRIPTION

Filter creates a new Array of items which evaluate to true in the supplied function. 
In the Array.every() method, we tested if the entire Array was composed of Numbers. 
In Array.filter() we can extract all the numbers, creating a new Array in the process.
This method will pass the current value, the current index, and a pointer to the array to your function. 
myfunction(curValue, curIndex, curArray)

EXAMPLE

var isNumeric = function(x) {
   // returns true if x is numeric and false if it is not.
   var RegExp = /^(-)?(\d*)(\.?)(\d*)$/; 
   return String(x).match(RegExp);
}
var myArray = [1,'two',3,'four',5,'six',7,'eight',9,'ten'];
var oddArray=myArray.filter(isNumeric);
document.writeln(oddArray);   // outputs: 1,3,5,7,9

*/

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}

/*

Array.forEach(function)

DESCRIPTION

This is an odd little method. 
All it does is pass each element of the Array to the passed function. 
It ignores any results from the function and it returns nothing itself. 
It will pass all the Array contents through the function of your choice but the Array itself will not be affected and it will return nothing by itself.
This method will pass the current value, the current index, and a pointer to the array to your function. 
myfunction(curValue, curIndex, curArray) 

EXAMPLE

var printArray = function (x, idx) {
   document.writeln('['+idx+'] = '+x);
}
var myArray = [1,'two',3,'four',5];
myArray.forEach(printArray); // outputs: [0] = 1 [1] = two [2] = 3 [3] = four [4] = 5

*/

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        fun.call(thisp, this[i], i, this);
    }
  };
}

/*

Array.map(function)

DESCRIPTION

The map method will call the provided function for each value of the array and it will return an array containing the results of those function calls.
The callback function is called with three arguments: the value, the index, and a pointer to the array being used respectively.
In the following example each element of the array is tested to see if it is numeric, if it is, it's passed into the new array, otherwise a zero is inserted. 

EXAMPLE

var isNumeric = function(x) {
   // returns true if x is numeric and false if it is not.
   var RegExp = /^(-)?(\d*)(\.?)(\d*)$/; 
   return String(x).match(RegExp);
}
var testElement = function(x) {
   if (isNumeric(x)) {
      return x;
   } else {
      return 0;
   }
}
var myArray = [1,'two',3,'four',5,'six',7,'eight',9,'ten'];
var newArray= myArray.map(testElement);
document.writeln(newArray); // outputs: 1,0,3,0,5,0,7,0,9,0

*/

if (!Array.prototype.map)
{
  Array.prototype.map = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array(len);
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        res[i] = fun.call(thisp, this[i], i, this);
    }

    return res;
  };
}

/*

Array.find(searchStr)

DESCRIPTION

First it will return an array of all the indexes it found (it will return false if it doesn't find anything). 
Second in addition to passing the usual string or number to look for you can actually pass a regular expression, which makes this the ultimate Array prototype in my book.

EXAMPLE

var tmp = [5,9,12,18,56,1,10,42,'blue',30, 7,97,53,33,30,35,27,30,'35','Ball', 'bubble'];
//         0/1/2 /3 /4/5 /6 /7     /8  /9/10/11/12/13/14/15/16/17/  18/    19/      20
var thirty=tmp.find(30);             // Returns 9, 14, 17
var thirtyfive=tmp.find('35');       // Returns 18
var thirtyfive=tmp.find(35);         // Returns 15
var haveBlue=tmp.find('blue');       // Returns 8
var notFound=tmp.find('not there!'); // Returns false
var regexp1=tmp.find(/^b/);          // returns 8,20    (first letter starts with b)
var regexp1=tmp.find(/^b/i);         // returns 8,19,20 (same as above but ignore case)

*/

Array.prototype.find = function(searchStr) {
  var returnArray = false;
  for (i=0; i<this.length; i++) {
    if (typeof(searchStr) == 'function') {
      if (searchStr.test(this[i])) {
        if (!returnArray) { returnArray = [] }
        returnArray.push(i);
      }
    } else {
      if (this[i]===searchStr) {
        if (!returnArray) { returnArray = [] }
        returnArray.push(i);
      }
    }
  }
  return returnArray;
}

/*

Array.compare(array)

DESCRIPTION

If you need to be able to compare Arrays this is the prototype to do it. 
Pass an Array you want to compare and if they are identical the method will return true. 
If there's a difference it will return false. The match must be identical so '80' is not the same as 80.

EXAMPLE

var myArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var yourArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
document.writeln(myArray.compare(yourArray)); // outputs: true;

yourArray[0]='1';
document.writeln(myArray.compare(yourArray)); // outputs: false;
yourArray[0]='one';
document.writeln(myArray.compare(yourArray)); // outputs: false;
yourArray[0]=1;
document.writeln(myArray.compare(yourArray)); // outputs: true;

*/

Array.prototype.compare = function(testArr) {
    if (this.length != testArr.length) return false;
    for (var i = 0; i < testArr.length; i++) {
        if (this[i].compare) { 
            if (!this[i].compare(testArr[i])) return false;
        }
        if (this[i] !== testArr[i]) return false;
    }
    return true;
}


Array.prototype.contains = function(searchStr) {
    for (i = 0; i < this.length; i++) {
        if (typeof (searchStr) == 'function') {
            if (searchStr.test(this[i])) {
                return true;
            }
        } else {
            if (this[i] === searchStr) {
                return true;
            }
        }
    }
    return false;
};

Array.prototype.findFirst = function(fun) {
    var len = this.length;
    if (typeof fun != "function")
        throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++) {
        if (i in this) {
            var val = this[i]; // in case fun mutates this
            if (fun.call(thisp, val, i, this))
                return val;
        }
    }

    return null;
};