Skip to content

Instantly share code, notes, and snippets.

@eliperelman
Forked from 140bytes/LICENSE.txt
Created June 21, 2011 13:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eliperelman/1037838 to your computer and use it in GitHub Desktop.
Save eliperelman/1037838 to your computer and use it in GitHub Desktop.
Array.prototype.some polyfill for 140byt.es

Array.prototype.some polyfill for 140byt.es

Execute an expression for every element in an array and determine whether one of the elements make the expression evaluate truthy. This polyfill adds the some method to the array prototype for environments lower than ECMAScript 5.

Array.prototype.some = [].some || // Use the native every method if available, otherwise:
function (
a, // expression to test each element of the array against
b, // optionally change the 'this' context for the given callback
c, // placeholder iterator variable
d // placeholder variable (stores context of original array)
) {
for (c = 0, d = this; c < d.length; c++) // iterate over all of the array elements
if (a.call(b, d[c], c, d)) // call the given expression, passing in context, value, index, and original array
return !0; // if any expression evaluates true, immediately return since 'some' is true
return !1 // otherwise return false since all callbacks evaluated to false
}
Array.prototype.some=[].some||function(a,b,c,d){for(c=0,d=this;c<d.length;c++)if(a.call(b,d[c],c,d))return!0;return!1}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 Eli Perelman <http://eliperelman.com>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "ArrayPrototypeSomePolyfill",
"description": "Array some polyfill method for ECMAScript versions older than 5.",
"keywords": [
"Array",
"prototype",
"some",
"polyfill",
"ecmascript5"
]
}
<!DOCTYPE html>
<title>Array.prototype.some polyfill</title>
<script>
Array.prototype.some=[].some||function(a,b,c,d){for(c=0,d=this;c<d.length;c++)if(a.call(b,d[c],c,d))return!0;return!1}
var arr = [2,4,6,8,10,12,14,16];
var arr2 = [1,2,3,4,5,6,7,8];
// logs true, since at least 'some' elements are less than 10
console.log(arr.some(function(value, index, myArray) {
return value < 10;
});
// logs false, since none of the values are greater than 20 or none of arr2 values are greater than 10
console.log(arr.some(function(value, index, myArray) {
// this refers to arr2, but myArray is still arr
return this[index] > 10 || value > 20;
}, arr2);
</script>
@atk
Copy link

atk commented Jun 21, 2011

Saving some additional bytes:

Array.prototype.some=[].some||function(a,b,c,d,e){for(c=0,d=this;c<d.length;c++)if(a.call(b,d[c],c,d))e=1;return!!e}

@atk
Copy link

atk commented Jun 21, 2011

And if the order of elements within the array doesn't matter, we can make this even shorter:

Array.prototype.some=[].some||function(a,b,c,d,e){for(d=this,c=d.length;c--;)if(a.call(b,d[c],c,d))e=1;return!!e}

@eliperelman
Copy link
Author

Very nice! I will update with your changes.

@eliperelman
Copy link
Author

Hmm, the one issue with this is that is doesn't return immediately after the first truthy expression is run. I wonder if the shorter bytes is worth the performance hit.

@atk
Copy link

atk commented Jun 21, 2011

Issue valid. My Suggestion: keep both variants.

@jdalton
Copy link

jdalton commented Aug 21, 2011

This fallback is not ES5 complaint.
Also browsers like Chrome have a bug where Array.prototype.some = [].some will cause Array#some to become enumerable.

@atk
Copy link

atk commented Aug 22, 2011

I would prefer a less dangerous version like [].some||(Array.prototype.some=function(){}), too. Yet I do not see why in hell this fallback should be a complaint. Unless, of course, you just let off some freudian slip on your own complaint about it not being compliant - which it probably is in three ways: 1. does not check hasOwnProperty - which shouldn't do anything in modern browsers unless you play too much with prototypes - and if that is the case, shame on you, 2. doesn't replace b with d if not present, 3. may not have a length property of 1.

Anyway: If you can provide a better version within 140bytes, feel free to do so.

@jdalton
Copy link

jdalton commented Aug 22, 2011

Yet I do not see why in hell this fallback should be a complaint.

Fallbacks should be compliant with ES5 because you are modifying the Array.prototype and other scirpts after may assume that a fully functional and complaint method exists. By not following spec you create an inconsistency in use between browsers that do and don't support the native method.

Anyway: If you can provide a better version within 140bytes, feel free to do so.

I don't think ES5 fallbacks are the best choice for code golf in general because things should be really tight and follow spec as these methods are added to native prototypes.

@atk
Copy link

atk commented Aug 22, 2011

RFC 1925, 1: "It has to work." - This is true for polyfills as well.

@jdalton
Copy link

jdalton commented Aug 22, 2011

@atk see my comment on Function#bind.

For more information on what can be changed to make this method ES5 compliant and info on a critical bug, that this gist shares, please see my comments on a similar Array#filter gist.

@atk
Copy link

atk commented Oct 6, 2011

Taking care of sparse arrays while also saving space (77bytes left):

[].some||(Array.prototype.some=function(a,b,c,d){d=this;for(c in d)if(a.call(b,d[c],c,d))return!0;return!1})

Disclaimer: If you want to have it all secured against prototype madness, you can throw in a hasOwnProperty check.

@jdalton
Copy link

jdalton commented Oct 6, 2011

@atk nice, lots of space left for smth like (115 bytes):

[].some||(Array.prototype.some=function(a,b,c,d){d=this;for(c in d)if(c==+c&&a.call(b,d[c],c,d))return!0;return!1})

which would avoid most problem keys but still allow keys like "03"... OR (125 bytes)

[].some||(Array.prototype.some=function(a,b,c,d){d=this;for(c in d)if(~~c+''==c&&c>-1&&a.call(b,d[c],c,d))return!0;return!1})

which should avoid that edge case issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment