I am trying to check if all my values are defined in an array of mine. My code is the following
var check = function (item){return item !== undefined;};
array.every(check);
I tried it on the following arrays:
var array = [];
array[5] = 0; //[undefined × 5, 0]
array.every(check); //return true although there are 5 udefined values there
What am I doing wrong?
As said above every skips "holes".
If you really want this functionality then you can add this simple method:
Array.prototype.myEvery= function (pred) {
for (var i = 0; i < this.length; i++) {
if (!pred(this[i])) return false;
}
return true;
}
MDN provides a polyfill (read: the exact code) for Array.every. If we just modify this to remove the check that the property exists, it's easy:
if (!Array.prototype.reallyEvery) {
Array.prototype.reallyEvery = function(callbackfn, thisArg) {
'use strict';
var T, k;
if (this == null) {
throw new TypeError('this is null or not defined');
}
// 1. Let O be the result of calling ToObject passing the this
// value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method
// of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
// 4. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (typeof callbackfn !== 'function') {
throw new TypeError();
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 1) {
T = thisArg;
}
// 6. Let k be 0.
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// i. Let kValue be the result of calling the Get internal method
// of O with argument Pk.
kValue = O[k];
// ii. Let testResult be the result of calling the Call internal method
// of callbackfn with T as the this value and argument list
// containing kValue, k, and O.
var testResult = callbackfn.call(T, kValue, k, O);
// iii. If ToBoolean(testResult) is false, return false.
if (!testResult) {
return false;
}
k++;
}
return true;
};
}
I've just renamed it to Array.reallyEvery().
That's because the .every() method checks if the value exists, before calling your check() function, so check() will only be called for the last element (0).
NOTE: Remember also that the .every() method stops if your function returns a false value.
Try this instead, if you want to check:
var array = [1, 2, undefined, undefined, 1];
var check = function (item){return item !== undefined;};
array.every(check)
// this will work for 1 and 2, but will stop at the third element
array.every(function(item) {console.log(item); return true;});
// this will log all the elements, because the function always returns true
Try below.
Array.prototype.every = function(){
for(var i=0;i<this.length;i++){
if(this[i]==undefined)
return false;
}
return true;
}
var array = [];
array[5] = 0;
console.log(array.every());
Because the lenght of the array is predetermined I managed to bypass this by using filter function.
var check = function (item) {return item !== undefined};
array.filter(check).length === predeterminedLength;
Thank you all for answering!!As always great community
Related
So i've come up with a basic solution to a problem which returns an array:
function doubleAll(numbers) {
var result = []
numbers.map(function(val, i){
result.push(val*2);
})
return result
}
however the official solution simply uses a double return statment and I'm trying to understand the order of opperations and how it is actually working.
function doubleAll(numbers) {
return numbers.map(function double(num) {
return num * 2
})
}
I'm kind of interested in what is happening behind the scenes and the differences between the two ways of doing it.
The map() method creates a new array with the results of calling a
provided function on every element in this array.
So in your example:
function doubleAll(numbers) {
return numbers.map(function double(num) {
return num * 2
}) //returns array
}
and
function doubleAll(numbers) {
var result = [];
numbers.map(function(val, i){
result.push(val*2); //pushing value into result array
});
return result;
}
In second example the resource is getting wasted since map returns an array and it never used, which can still be achieved using forEach method without wasting resource:
function doubleAll(numbers) {
var result = [];
numbers.forEach(function(val, i){
result.push(val*2); //pushing value into result array
});
return result;
}
This polyfill will add more clarity about .map:
Ref from MDN:
// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.io/#x15.4.4.19
if (!Array.prototype.map) {
Array.prototype.map = function(callback, thisArg) {
var T, A, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
// 1. Let O be the result of calling ToObject passing the |this|
// value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal
// method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 1) {
T = thisArg;
}
// 6. Let A be a new array created as if by the expression new Array(len)
// where Array is the standard built-in constructor with that name and
// len is the value of len.
A = new Array(len);
// 7. Let k be 0
k = 0;
// 8. Repeat, while k < len
while (k < len) {
var kValue, mappedValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal
// method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal
// method of O with argument Pk.
kValue = O[k];
// ii. Let mappedValue be the result of calling the Call internal
// method of callback with T as the this value and argument
// list containing kValue, k, and O.
mappedValue = callback.call(T, kValue, k, O);
// iii. Call the DefineOwnProperty internal method of A with arguments
// Pk, Property Descriptor
// { Value: mappedValue,
// Writable: true,
// Enumerable: true,
// Configurable: true },
// and false.
// In browsers that support Object.defineProperty, use the following:
// Object.defineProperty(A, k, {
// value: mappedValue,
// writable: true,
// enumerable: true,
// configurable: true
// });
// For best browser support, use the following:
A[k] = mappedValue;
}
// d. Increase k by 1.
k++;
}
// 9. return A
return A;
};
}
The map method of an array will execute a callback on each member of the array and returns the resulting array.
function doubleAll(numbers) {
return numbers.map(function double(num) {
return num * 2
}) //returns an array whose members have each been passed to double(num)
}
In this case doubleAll() is returning the results of numbers.map(), which is an array whose members have been mutated by the callback function double(num).
I have the following code but it doesn't seem to work in IE8. I've read IE8 doesn't support array.prototype.foreach. How can you fix this in IE8?
[].forEach.call(data.Results.cars, function(inst){
// Fetching the value of key _
var _html = inst["_"];
// Fetching the src of image by making string a jquery object
var _src = $(_html).find("img").attr("src");
//Extracting the image's name
var _imagesName = _src.match(/([^\/]+)(?=\.\w+$)/)[0];
// Building html
var _h = '<div >'
+'<img src="'+_src+'" >'
+'<p>'+_imagesName+'</p>'
+'<p><input type="radio" value="'+imagesName'" name="cartype"> </p>'
+'</div>';
// Appending html to #results
$("#results").append(_h);
});
Array#forEach is not supported by IE8 it is supported by IE9 and later, see Browser Compatibility
You can use for or polyfill from MDN
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 1) {
T = thisArg;
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as the this value and
// argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
I am currently learning javascript from the definitive guide and many code examples use xyx.call(undefined,/*args*/) instead of just calling the function as xyz(/*args*/).
I know that if the executing context is set to undefined then the value of this will refer to the global object . I'am not able to figure out why this is done in most examples as they don't depends on values from the global object. Can anybody help me understand the difference.
Some implementation of Array.protype.reduce
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(callbackfn, initialValue) {
"use strict";
var O = Object(this),
lenValue = O.length,
len = lenValue >>> 0,
k,
accumulator,
kPresent,
Pk,
kValue;
if (typeof callbackfn !== 'function') {
throw new TypeError();
}
if (len === 0 && initialValue === undefined) {
throw new TypeError();
}
k = 0;
if (initialValue !== undefined) {
accumulator = initialValue;
} else {
kPresent = false;
while(!kPresent && k < len) {
Pk = k.toString();
kPresent = O.hasOwnProperty(Pk);
if (kPresent) {
accumulator = O[Pk];
}
k += 1;
}
if (!kPresent) {
throw new TypeError();
}
}
while(k < len) {
Pk = k.toString();
kPresent = O.hasOwnProperty(Pk);
if (kPresent) {
kValue = O[Pk];
accumulator = callbackfn.call(undefined, accumulator, kValue, k, O);
}
k += 1;
}
return accumulator;
};
}
and some use :
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(callback /*, initialValue*/) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.reduce called on null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
var t = Object(this), len = t.length >>> 0, k = 0, value;
if (arguments.length == 2) {
value = arguments[1];
} else {
while (k < len && ! k in t) {
k++;
}
if (k >= len) {
throw new TypeError('Reduce of empty array with no initial value');
}
value = t[k++];
}
for (; k < len; k++) {
if (k in t) {
value = callback(value, t[k], k, t);
}
}
return value;
};
}
so in one method the callback function is called using call() and in other implementation its not
JavaScript is functional OO language.It have different pattern to invoke a function. xyz(/*args*/) and xyx.call(undefined,/*args*/) are two different kind of invocations.
xyz(/*args*/) - In this case this have window as its value.
xyx.call(undefined,/*args*/) - In this case this will be nothing but context whatever we pass in call like in this case undefined.
Only special thing of using xyx.call(undefined,/*args*/) is that you have reliability of choosing your context in your function call.When you are writing object oriented JavaScript at that time value of context matters a lot. That's why it is more explicit to use xyx.call(undefined,/*args*/) over xyz(/*args*/).
The reason your examples are using call for Array functions has to do with JavaScript's multiple (somewhat needless) array types.
As well as the standard object type that returns true on arr instanceof Array, there are also NodeLists returned from a document.querySelectorAll function, and other similar types. The important thing is, these other types don't have all of Array's helper functions (reduce, map, forEach).
However, they still have all that they technically need for those functions to work; and the .call method helps you to do that. So, let's say I have two collections.
var arr = [1,2,3];
var nodelist = document.querySelectorAll('.baby');
arr.map(function(val) { return val + 1; }); // Okay!
nodelist.map(function(val) { return val.innerHTML; }); // doesn't work
I can pull off the .map call on the nodelist with call, by giving it a different target-object.
Array.prototype.map.call(nodelist, function...etc)
// Technically, this works too; just grabbing the method from our arr
// instance, but it's cleaner to refer to the original
// type's method.
arr.map.call(nodelist, function...etc)
To explain the code samples you posted; those are "polyfills" - browsers should have a "reduce" function themselves, but older browsers might not. So, we create it ourselves to replicate the same functionality.
Is it possible to perform a single function on multiple objects by e.g. grouping them. What I want to do is something like:
{object1, object2, object3}.toFront();
A simple way:
var nodes = [node.rectangle1, node.text, node.rectangle2];
for (var i = 0; i < nodes.length; i++) {
nodes[i].toFront();
}
If you use underscore and like brevity:
_.invoke([node.rectangle1, node.text, node.rectangle2], 'toFront');
If you want the return values you can use map or if you just want some extra processing look at each.
EDIT (to make this complete):
You can also use the built-in forEach (if you don't care about some browsers or you choose to shim it) in a very similar fashion to the underscore each:
[node.rectangle1, node.text, node.rectangle2].forEach(function(el) {
el.toFront();
});
While you've already accepted an answer, this is possible in a similar manner either natively through JavaScript 1.6/ECMAScript 5th Edition:
function logElementID(element, index, array) {
var el = array[index],
prop = el.textContent ? 'textContent' : 'innerText';
el[prop] = el.id;
}
[document.getElementById('one'), document.getElementById('two')].forEach(logElementID);
JS Fiddle demo.
Or by extending the Object prototype:
function doStuff (el) {
console.log(el);
};
Object.prototype.actOnGroup = function(func){
var els = this.length ? this : [this];
for (var i = 0, len = els.length; i<len; i++){
func(els[i]);
}
return this;
};
document.getElementsByTagName('div').actOnGroup(doStuff);
document.getElementById('one').actOnGroup(doStuff);
JS Fiddle demo.
Or by, similarly, extending the Array prototype:
function doStuff (el) {
console.log(el);
};
Array.prototype.actOnGroup = function(func){
var els = this.length ? this : [this];
for (var i = 0, len = els.length; i<len; i++){
func(els[i]);
}
return this;
};
[document.getElementById('one'), document.getElementById('two')].actOnGroup(doStuff);
JS Fiddle demo.
Incidentally, if you'd like to provide a forEach() alternative to users without (relatively) up-to-date JavaScript implementations, the Mozilla Developer Network page for forEach() offers the following as '[an] algorithm 100% true to the ECMA-262, 5th edition':
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.com/#x15.4.4.18
if (!Array.prototype.forEach) {
Array.prototype.forEach = function forEach(callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError("this is null or not defined");
}
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0; // Hack to convert O.length to a UInt32
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if ({}.toString.call(callback) !== "[object Function]") {
throw new TypeError(callback + " is not a function");
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (thisArg) {
T = thisArg;
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (Object.prototype.hasOwnProperty.call(O, k)) {
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as the this value and
// argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
Copied verbatim, from the reference (below) from the MDN forEach() article; 01/04/2013, at 14:30.
References:
Array.forEach().
I need the index of the first value in the array, that matches a custom compare function.
The very nice underscorej has a "find" function that returns the first value where a function returns true, but I would need this that returns the index instead. Is there a version of indexOf available somewhere, where I can pass a function used to comparing?
Thanks for any suggestions!
Here's the Underscore way to do it - this augments the core Underscore function with one that accepts an iterator function:
// save a reference to the core implementation
var indexOfValue = _.indexOf;
// using .mixin allows both wrapped and unwrapped calls:
// _(array).indexOf(...) and _.indexOf(array, ...)
_.mixin({
// return the index of the first array element passing a test
indexOf: function(array, test) {
// delegate to standard indexOf if the test isn't a function
if (!_.isFunction(test)) return indexOfValue(array, test);
// otherwise, look for the index
for (var x = 0; x < array.length; x++) {
if (test(array[x])) return x;
}
// not found, return fail value
return -1;
}
});
_.indexOf([1,2,3], 3); // 2
_.indexOf([1,2,3], function(el) { return el > 2; } ); // 2
There's a standard function in ECMAScript 2015 for Array.prototype.findIndex(). Currently it's implemented in all major browsers apart from Internet Explorer.
Here's a polyfill, courtesy of the Mozilla Developer Network:
// https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
if (!Array.prototype.findIndex) {
Object.defineProperty(Array.prototype, 'findIndex', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return k.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return k;
}
// e. Increase k by 1.
k++;
}
// 7. Return -1.
return -1;
},
configurable: true,
writable: true
});
}
You could do something like this:
Array.prototype.myIndexOf = function(f)
{
for(var i=0; i<this.length; ++i)
{
if( f(this[i]) )
return i;
}
return -1;
};
Regarding Christian's comment: if you override a standard JavaScript method with a custom one with a different the same signature and different functionality, bad thing will likely happen. This is especially true if you're pulling in 3rd party libraries which may depend on the original, say, Array.proto.indexOf. So yeah, you probably want to call it something else.
As others have noted, easy enough to roll your own, which you can keep short and simple for your particular use case:
// Find the index of the first element in array
// meeting specified condition.
//
var findIndex = function(arr, cond) {
var i, x;
for (i in arr) {
x = arr[i];
if (cond(x)) return parseInt(i);
}
};
var moreThanTwo = function(x) { return x > 2 }
var i = findIndex([1, 2, 3, 4], moreThanTwo)
Or if you're a CoffeeScripter:
findIndex = (arr, cond) ->
for i, x of arr
return parseInt(i) if cond(x)
The javascript array method filter returns a subset of the array that return true from the function passed.
var arr= [1, 2, 3, 4, 5, 6],
first= arr.filter(function(itm){
return itm>3;
})[0];
alert(first);
if you must support IE before #9 you can 'shim' Array.prototype.filter-
Array.prototype.filter= Array.prototype.filter || function(fun, scope){
var T= this, A= [], i= 0, itm, L= T.length;
if(typeof fun== 'function'){
while(i<L){
if(i in T){
itm= T[i];
if(fun.call(scope, itm, i, T)) A[A.length]= itm;
}
++i;
}
}
return A;
}
How about such find function ?
(function () {
if (!Array.prototype._find) {
Array.prototype._find = function (value) {
var i = -1, j = this.length;
if (typeof(value)=="function")
for(; (++i < j) && !value(this[i]););
else
for(; (++i < j) && !(this[i] === value););
return i!=j ? i : -1;
}
}
}());
Here comes the coffeescript version of nrabinowitz's code.
# save a reference to the core implementation
indexOfValue = _.indexOf
# using .mixin allows both wrapped and unwrapped calls:
# _(array).indexOf(...) and _.indexOf(array, ...)
_.mixin ({
# return the index of the first array element passing a test
indexOf: (array, test) ->
# delegate to standard indexOf if the test isn't a function
if (!_.isFunction(test))
return indexOfValue(array, test)
# otherwise, look for the index
for item, i in array
return i if (test(item))
# not found, return fail value
return -1
})
using underscore I came up with something copied from their find implementation using _.any:
findIndex = function (obj, iterator, context) {
var idx;
_.any(obj, function (value, index, list) {
if (iterator.call(context, value, index, list)) {
idx = index;
return true;
}
});
return idx;
};
What do you think - do you have any better solutions?