I was looking on MDN for a polyfill for Array.prototype.includes() and I came across the Object() syntax below:
if (!Array.prototype.includes) {
Array.prototype.includes = function(searchElement /*, fromIndex*/) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.includes called on null or undefined');
}
//This is the line in question
var O = Object(this);
var len = parseInt(O.length, 10) || 0;
if (len === 0) {
return false;
}
var n = parseInt(arguments[1], 10) || 0;
var k;
if (n >= 0) {
k = n;
} else {
k = len + n;
if (k < 0) {k = 0;}
}
var currentElement;
while (k < len) {
currentElement = O[k];
if (searchElement === currentElement ||
(searchElement !== searchElement && currentElement !== currentElement)) { // NaN !== NaN
return true;
}
k++;
}
return false;
};
}
What is Object(this) doing and what is the purpose of this in this case?
Object(...) converts the passed value to an object. It simply returns the value itself if it is already an object, otherwise wit will create a new object and return that.
From the spec:
When Object is called as a function rather than as a constructor, it performs a type conversion.
Example:
var obj = Object("foo");
// same as
// var obj = new String("foo");
what is the purpose of this in this case?
It ensures that the value is an object, not a primitive. The implementation just follows the spec:
Let O be ? ToObject(this value).
Related
With the regular built in reduce function, if you don't assign an initial start value, it starts wrapping over the first 2 array values. Is there a way to do that with a forEach instead of the forLoop I have now? I tried using a forEach but I didn't know how to get it start from arr[1]. If I use a forEach like the 2nd conditional, it gives me 11 instead of 10.
function reduce(arr, callback, start) {
if (start === undefined) {
var current = arr[0];
for (var i = 1; i < arr.length; i++) {
current = callback(current, arr[i]);
}
return current;
}
else {
var current = start;
arr.forEach(function(e) {
current = callback(current, e);
});
return current;
}
}
console.log(reduce([1, 2, 3, 4], function(a, b) {
return a + b;
})); //-> should return 10
Found this polyfill to add reduce to browsers that don't support it.
// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
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;
};
}
I understand there are other pages on this but I am trying to get my own working and I do not know why it is not working. I am new to node.js.
for (var index in output)
{
if (opt.options.showEmpty != true)
{
var check = arrayIsEmpty(output[index]);
if ( check == true )
{
continue;
}
else
{
var array = removingEmptyString(output[index]);
console.log(index + "\t" + array);
//console.log(index+ "\t" + output[index]);
}
}
}
function removingEmptyString(array)
{
var newArray;
for( var i = 0; i < array.length; i++)
{
if(array[i] != "" || array[i] != null)
{
newArray[i] = array[i];
}
}
return newArray;
}
My result is tree,,, that i was previously getting before the code i wrote. now i get an error of
newArray[i] = array[i];
^
TypeError: Cannot set property '0' of undefined
at removingEmptyString (librarySeeker.js:130:18)
at result (librarySeeker.js:76:19)
at /async/lib/async.js:226:13
at async/lib/async.js:113:25
at async/lib/async.js:24:16
at async/lib/async.js:223:17
at /async/lib/async.js:510:34
at IncomingMessage.<anonymous> (pull.js:295:10)
at IncomingMessage.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:910:16
You could just use the .filter method in Array's prototype.
var pirate = ['a','1','',0];
function arr (value) {
return value.filter(function (item) {
return item !== '';
});
}
arr(pirate);
// <- ['a','1',0]
As an alternative, you might want to consider naming the callback to .filter
var pirate = ['a','1','',0];
function worthy (value) {
return value !== '';
}
pirate.filter(worthy);
// <- ['a','1',0]
In the spirit of learning, here is a working version of your solution:
function removingEmptyString(array) {
'use strict';
var newArray = []; // don't forget to initialize it
for( var i = 0, len = array.length; i < len; i += 1) {
if(typeof array[i] === 'string' && array[i].length > 0) {
// add the string to the end of the new array
newArray.push(array[i]);
}
}
return newArray;
}
The error is saying that newArray has not been initialised, so it cannot assign the 0 property to an undefined object.
You can improve your function to make it work:
function removingEmptyString(array){
var newArray = [];
for( var i = 0; i < array.length; i++){
// empty string and null are falsy values by default is js
if(array[i])
{
// use this if you want to keep "undefined" values in the newArray in place
// of the null ones in the original array
newArray[i] = array[i];
// otherwise just push the values in the new array
// newArray.push(array[i]);
}
}
return newArray;
}
it looks like easy but I kind of stuck in trying to figure out how to filter data before pushing json data into javascript array.
//push data into javascript array [timestamp,value]
dataJSON2 = [];
for (i in parsed2) {
if (parsed2[i].value == 'open' || parsed2[i].value == 'true' ) {
thevalue = 1;
} else if (parsed2[i].value == 'closed' || parsed2[i].value == 'false' ) {
thevalue = 0;
} else {
thevalue = parsed2[i].value;
}
dataJSON2.push( [ (parsed2[i].timestamp),
parseFloat (thevalue) ] );
}
what I am trying to accomplish is if current thevalue var is the same with the previous thevalue then it would discard the data and go to the next i until it return different value.
It would be easy if using for looping but I don't know different way to push json object rather than for..in, nor to use filtering i value before pushing it.
var dataJSON2 = [], previous;
for (i in parsed2) {
if (parsed2[i].value === 'open' || parsed2[i].value === 'true' ) {
thevalue = 1;
} else if (parsed2[i].value === 'closed' || parsed2[i].value === 'false' ) {
thevalue = 0;
} else {
thevalue = parsed2[i].value;
}
if (previous === thevalue) continue;
previous = thevalue;
dataJSON2.push( [ (parsed2[i].timestamp), parseFloat (thevalue) ] );
}
This would check for previous value with the current value and skip it if they are same
dataJSON2 = [];
var lastVal = parsed2 && parsed2[0];
for (var i = 1; i < parsed2.length; i++) {
if (lastVal !== parsed2[i].value) {
dataJSON2.push([(parsed2[i].timestamp), parseFloat(parsed2[i].value)]);
lastVal = parsed2[i];
}
}
Extracted from Array.indexOf from MDN
Create a function like this
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
'use strict';
if (this == null) {
throw new TypeError();
}
var n, k, t = Object(this),
len = t.length >>> 0;
if (len === 0) {
return -1;
}
n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
for (k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
};
}
and use indexOf like this
if (dataJSON2.indexOf( [ (parsed2[i].timestamp), parseFloat (thevalue) ] ) == -1){
dataJSON2.push( [ (parsed2[i].timestamp), parseFloat (thevalue) ] );
}
can some one tell me how can i remove string element from an array
i have google this and all i get is removing by index number
my example :
var myarray = ["xyz" , "abc" , "def"] ;
var removeMe = "abc" ;
myarray.remove(removeMe) ;
consle.log(myarray) ;
this is what i get from the console :
Uncaught TypeError: Object xyz,abc,def has no method 'remove'
jsfiddle
Since you're using jQuery
myarray.splice($.inArray("abc", myarray), 1);
EDIT
If the item isn't in the array, this 'one-liner' will likely throw an error. Something a little better
var index = $.inArray("abc", myarray);
if (index>=0) myarray.splice(index, 1);
From https://stackoverflow.com/a/3955096/711129:
Array.prototype.remove= function(){
var what, a= arguments, L= a.length, ax;
while(L && this.length){
what= a[--L];
while((ax= this.indexOf(what))!= -1){
this.splice(ax, 1);
}
}
return this;
}
var ary = ['three', 'seven', 'eleven'];
ary.remove('seven')
or, making it a global function:
function removeA(arr){
var what, a= arguments, L= a.length, ax;
while(L> 1 && arr.length){
what= a[--L];
while((ax= arr.indexOf(what))!= -1){
arr.splice(ax, 1);
}
}
return arr;
}
var ary= ['three','seven','eleven'];
removeA(ary,'seven')
You have to make a function yourself. You can either loop over the array and remove the element from there, or have this function do it for you. Either way, it is not a standard JS feature.
Try like below,
myarray.splice(myarray.indexOf(removeMe),1);
You can add this below script (from MDN) for browsers that doesn't support indexOf
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 0) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
}
}
more simple solution
var myarray = ["xyz" , "abc" , "def"];
var removeMe = "abc";
var theNewArray = myarray.filter(s => s !== removeMe);
console.log(theNewArray); // will return ["xyz" , "def"]
I used the code described here but now, when I do a "for ... in ..." cicle, it gets the function "indexOf" as an index position of the array...
Example Code:
var the_array=new Array();
for (key in the_array){
console.log(key +" - "+the_array[key]);
}
This code shows this in the console:
indexOf - function (searchElement /*, fromIndex */ ) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 0) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
}
How could I prevent the function from appearing as a key on the array?
Btw, I know that I can use the inArray function of jquery but, in this case, I would like to use the "indexOf" function...
It's a bad idea to use for...in on arrays, for this and other reasons. See my answer here:
Why is 'for(var item in list)' with arrays considered bad practice in JavaScript?