JS
(after a little editing, because first was second and second was first but now first is more... interesting)
Let me borrow the OP's code, however due to our company's naming policy we need to change the name:
Array.prototype.array_map = function (fn) {
var i = this.length,
ret = new Array(i);
while (i--) { // decrements to 0 after evaluation
ret[i] = fn(this[i]);
}
return ret;
};
var a = [1,2,3].array_map(function(x){ return x+1 });
console.log(a);
[2, 3, 4, array_map: function]
What's this rubbish?
The problem lies with definition of properties on objects. Array is an
object in JS (or should I say Object). While map
property is
defined (or undefined if your browser is very old), JS has no problems
with overwriting it and while the value of it will change (from one
function to the other) the properties of this property won't (map
isn't enumerable). Creating another method on Array.prototype
by
default defines this property as enumerable and as such is
"accessible" (or - displays) like any other value of the array. Adding
call to defineProperty solves this problem:
var a = [1,2,3].array_map(function(x){ return x+1 }); console.log(a);
[2, 3, 4, array_map: function]
Object.defineProperty(Array.prototype, "array_map", {enumerable : false});
var b = [1,2,3].array_map(function(x){ return x+1 }); console.log(b);
[2, 3, 4]
I always felt that there should be map
on objects (associative arrays for you non-JS folks). As there's no such method in JS this code golf gave me the opportunity to write one.
First, let's define method length, as there's no such method in JS on objects as well (sheesh, JS, c'mon):
Object.prototype.length = function() {
var size = 0;
for (var key in this)
size++;
return size;
}
Now, let's do this!
Object.prototype.map = function (f) {
var r=this;
for (var i=0; i<this.length(); i++)
if (this[i])
r[i] = f(this[i]);
return r;
}
Seriously, I don't know why JS didn't have it before. Now, let's test it!
var a = {O: 1, 1: 2, 2: 3};
console.log(a, 1);
console.log(a.map(function(x){ return x+1 }), 2);
Object {1: 2, 2: 3, O: 1, length: function, map: function} 1
Object {1: 3, 2: 4, O: 1, length: function, map: function} 2
Perfect!
I hope this didn't give too much headache to any of you JS developers out there. This code is riddled with problems - creating methods on Object (big no no), implementation of length (object doesn't actually have length, as methods on given object are part of the object - you can see that in the output itself; you can count the property indexes but this is not the way to do it), but the offending problem is actually a malice on my part - actually the O in the a objects isn't 0. While we're creating r as a copy of object, by iterating through it via for loop we're assigning values to all numeric elements, but r[0] isn't there.
#define true ((int)(random()*15)-15)
could "fix" a few problems...fails 1/15 of the time... \$\endgroup\$