How to extend the javascript Array Class? - javascript

I am trying to extend the Array class to add a Sum method to it. This is my code below, what am I doing wrong?
Class tipArray extends Array{
sum(values) {
for(i in values) {
total +=i;
}
}
}
var testArray = new tipArray();
testArray = [1,2,3,4];
console.log(testArray.sum());
Expected output = 10

Start by imagining how you would sum an array (maybe something with reduce).
Turn that into a function.
Add that as a method on your class. You can use this to refer to the array.
(optional) ask yourself if you really need a subclass instead of a function that accepts an array.
class tipArray extends Array{
sum() {
// Consider making sure the array contains items where sum makes sense here.
return this.reduce((sum, current) => sum + current)
}
}
var testArray = new tipArray(1,2,3,4);
console.log(testArray.sum());
// add another element and take another sum
testArray.push(10)
console.log(testArray.sum());

class tipArray extends Array {
sum() {
let val = 0;
for (let i = 0; i < this.length; i++) {
val += this[i];
}
return val;
}
}
var testArray = new tipArray(1, 2, 3, 4);
console.log(testArray.sum());
console.log(testArray.length);
Inside of the sum method, you refer to the array via this.

This seems to me more like asking for the solution of a homework after doing half the research on how to code in JavaScript.
Keywords, like class in JavaScript needs to be lowercase.
You didn't declare any of the variables. For example in the for loop you keep adding i to total, but what was the initial value of total? Declare the total variable before the for loop as let total = 0
The loop index i also needs to be declared as for (let i in values) {
The sum function doesn't return anything as you don't have any return statements. In this case JavaScript returns undefined and that is what you see in your console log. Add return total after your for loop so that the function would return something.
No need to use reduce here or extending array prototype as the issue isn't because for loop not being suitable to calculate sums.
You create a new instance of your own array class only to override it with a simple array at the next line with testArray = [1,2,3,4], as that line is the same as testArray = new Array(1, 2, 3, 4);. Write either var testArray = new tipArray(1, 2, 3, 4) or testArray.push(1, 2, 3, 4).
In essence the solution should be what Geuis wrote.

Related

Javascript how do i get my function array to give me more then the first value

function countUniqueItems(arr) {
nums = [];
for (i = 0; i < arguments.length; i++) {
const item = arr[i];
console.log(i);
//console.log(item);
if (nums.includes(arr) === true) {
//console.log('8 is in the array');
//nums.push(arr)
} else {
nums.push(arr);
//console.log('8 is NOT in the array');
//nums.push(item)
}
}
return nums;
}
countUniqueItems(1, 2);
So it will give back the first argument which is 1 but i want it to be able to say argument 2 and 3 and so on
So you need to pass an array into the function, in place of 1,2 pass [1,2].
Then inside your function, you should use arr.length in place of arguments.length.
Then you look at your logic for the loop, you are pushing atm arr into nums, but if you pass and array that isn't really want you want, you should be pushing item as that is the variable which represents your current element from the array.
It looks from you comments like you're trying to make a unique list of inputs. Perhaps something like this would do the trick.
EDIT: Updated to use arguments
function uniqueNumbers() {
let arrayOfArguments = [...arguments]
let uniqueNums = [];
arrayOfArguments.map(i => !uniqueNums.includes(i) ? uniqueNums.push(i) : null);
return uniqueNums;
};
console.log(uniqueNumbers(1,2,3,3));
you should either pass an array to countUniqueItems or use the arguments keyword in the for-loop.
Your code is only seeing 1 (as arr inside the function).
basic implementation to find unique items
function countUniqueItems(...arr) {
let nums = [];
for (let num of arr) {
if (nums.indexOf(num) === -1) nums.push(num);
}
return nums;
}
console.log(countUniqueItems(1, 2, 1));
Using Set you can remove the duplicate values, you dont need to do logic run the loop to find the unique values from array.
const a = [1,2,3,3];
const uniqueSet = new Set(a);
uniqueSet.size
let uniqueFinder = arr => { const uniqueSet = new Set(arr); return uniqueSet.size}
const arrywithduplicates = [1,2,3,3,4,4];
uniqueFinder(arrywithduplicates) // return 4
Read more about Set : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

Array in Javascript (array.forEach Vs array.map) [duplicate]

I know that there were a lot of topics like this. And I know the basics: .forEach() operates on original array and .map() on the new one.
In my case:
function practice (i){
return i+1;
};
var a = [ -1, 0, 1, 2, 3, 4, 5 ];
var b = [ 0 ];
var c = [ 0 ];
console.log(a);
b = a.forEach(practice);
console.log("=====");
console.log(a);
console.log(b);
c = a.map(practice);
console.log("=====");
console.log(a);
console.log(c);
And this is output:
[ -1, 0, 1, 2, 3, 4, 5 ]
=====
[ -1, 0, 1, 2, 3, 4, 5 ]
undefined
=====
[ -1, 0, 1, 2, 3, 4, 5 ]
[ 0, 1, 2, 3, 4, 5, 6 ]
I can't understand why using practice changes value of b to undefined.
I'm sorry if this is silly question, but I'm quite new in this language and answers I found so far didn't satisfy me.
They are not one and the same. Let me explain the difference.
forEach: This iterates over a list and applies some operation with side effects to each list member (example: saving every list item to the database) and does not return anything.
map: This iterates over a list, transforms each member of that list, and returns another list of the same size with the transformed members (example: transforming list of strings to uppercase). It does not mutate the array on which it is called (although the callback function may do so).
References
Array.prototype.forEach() - JavaScript | MDN
Array.prototype.map() - JavaScript | MDN
Array.forEach “executes a provided function once per array element.”
Array.map “creates a new array with the results of calling a provided function on every element in this array.”
So, forEach doesn’t actually return anything. It just calls the function for each array element and then it’s done. So whatever you return within that called function is simply discarded.
On the other hand, map will similarly call the function for each array element but instead of discarding its return value, it will capture it and build a new array of those return values.
This also means that you could use map wherever you are using forEach but you still shouldn’t do that so you don’t collect the return values without any purpose. It’s just more efficient to not collect them if you don’t need them.
forEach()
map()
Functionality
Performs given operation on each element of the array
Performs given "transformation" on a "copy" of each element
Return value
Returns undefined
Returns new array with transformed elements, leaving back original array unchanged.
Preferrable usage scenario and example
Performing non-tranformation like processing on each element. For example, saving all elements in the database.
Obtaining array containing output of some processing done on each element of the array. For example, obtaining array of lengths of each string in the array
forEach() example
chars = ['Hello' , 'world!!!'] ;
var retVal = chars.forEach(function(word){
console.log("Saving to db: " + word)
})
console.log(retVal) //undefined
map() example
chars = ['Hello' , 'world!!!'] ;
var lengths = chars.map(function(word){
return word.length
})
console.log(lengths) //[5,8]
The main difference that you need to know is .map() returns a new array while .forEach() doesn't. That is why you see that difference in the output. .forEach() just operates on every value in the array.
Read up:
Array.prototype.forEach() - JavaScript | MDN
Array.prototype.map() - JavaScript | MDN
You might also want to check out:
- Array.prototype.every() - JavaScript | MDN
Performance Analysis
For loops performs faster than map or foreach as number of elements in a array increases.
let array = [];
for (var i = 0; i < 20000000; i++) {
array.push(i)
}
console.time('map');
array.map(num => {
return num * 4;
});
console.timeEnd('map');
console.time('forEach');
array.forEach((num, index) => {
return array[index] = num * 4;
});
console.timeEnd('forEach');
console.time('for');
for (i = 0; i < array.length; i++) {
array[i] = array[i] * 2;
}
console.timeEnd('for');
forEach: If you want to perform an action on the elements of an Array and it is same as you use for loop. The result of this method does not give us an output buy just loop through the elements.
map: If you want to perform an action on the elements of an array and also you want to store the output of your action into an Array. This is similar to for loop within a function that returns the result after each iteration.
Hope this helps.
map returns a new array.
forEach has no return value.
That's the heart of the difference. Most of the other answers here say effectively that, but in a much more convoluted way.
forEach() :
return value : undefined
originalArray : not modified after the method call
newArray is not created after the end of method call.
map() :
return value : new Array populated with the results of calling a provided function on every element in the calling array
originalArray : not modified after the method call
newArray is created after the end of method call.
Conclusion:
Since map builds a new array, using it when you aren't using the returned array is an anti-pattern; use forEach or for-of instead.
The difference lies in what they return. After execution:
arr.map()
returns an array of elements resulting from the processed function; while:
arr.forEach()
returns undefined.
one of the shuttle difference not mentioned here is that forEach() can loop over static (not live) NodeList while map() cannot
//works perfectly
document.querySelectorAll('.score').forEach(element=>console.log(element));
//Uncaught TypeError: document.querySelectorAll(...).map is not a function
document.querySelectorAll('.score').map(element=>console.log(element));
Diffrence between Foreach & map :
Map() : If you use map then map can return new array by iterating main array.
Foreach() : If you use Foreach then it can not return anything for each can iterating main array.
useFul link : use this link for understanding diffrence
https://codeburst.io/javascript-map-vs-foreach-f38111822c0f
Difference between forEach() & map()
forEach() just loop through the elements. It's throws away return values and always returns undefined.The result of this method does not give us an output .
map() loop through the elements allocates memory and stores return values by iterating main array
Example:
var numbers = [2,3,5,7];
var forEachNum = numbers.forEach(function(number){
return number
})
console.log(forEachNum)
//output undefined
var mapNum = numbers.map(function(number){
return number
})
console.log(mapNum)
//output [2,3,5,7]
map() is faster than forEach()
One thing to point out is that both methods skips uninitialized values, but map keeps them in the returned array.
var arr = [1, , 3];
arr.forEach(function(element) {
console.log(element);
});
//Expected output: 1 3
console.log(arr.map(element => element));
//Expected output: [1, undefined, 3];
Performance Analysis (again - not very scientific)
In my experience sometime .map() can be faster than .foreach()
let rows = [];
for (let i = 0; i < 10000000; i++) {
// console.log("here", i)
rows.push({ id: i, title: 'ciao' });
}
const now1 = Date.now();
rows.forEach(row => {
if (!row.event_title) {
row.event_title = `no title ${row.event_type}`;
}
});
const now2 = Date.now();
rows = rows.map(row => {
if (!row.event_title) {
row.event_title = `no title ${row.event_type}`;
}
return row;
});
const now3 = Date.now();
const time1 = now2 - now1;
const time2 = now3 - now2;
console.log('forEach time', time1);
console.log('.map time', time2);
On my macbook pro (late 2013)
forEach time 1909
.map time 444
.map and .forEach will do just about then same thing, until you start operating on arrays with millions of elements. .map will create another collection with the same size (and possibly type, depending on the array species) which could use up a LOT of memory. .forEach will not do this.
const arr = [...Array(100000000).keys()];
console.time("for");
for (let i = 0; i < arr.length; i++) {}
console.timeEnd("for");
console.time("while");
let j = 0;
while (j < arr.length) {
j++;
}
console.timeEnd("while");
console.time("dowhile");
let k = 0;
do {
k++;
} while (k < arr.length);
console.timeEnd("dowhile");
console.time("forEach");
arr.forEach((element) => {});
console.timeEnd("forEach");
VM35:6 for: 45.998046875 ms
VM35:13 while: 154.581787109375 ms
VM35:20 dowhile: 141.97216796875 ms
VM35:24 forEach: 776.469970703125 ms
Map implicitly returns while forEach does not.
This is why when you're coding a JSX application, you almost always use map instead of forEach to display content in React.

How to replace array elements with another given array elements?

I want to make a function that completely override the original array.
function putDatainthis(arr) {
//....some ways to get data
arr = [data,data,data...]; //this just reassigns arr = to new array original that was passed as reference hasn't been modified.
}
//so right now only way i can think of is this:
function putDatainthis(arr) {
var data = [3,4,6,2,6,1];
arr.length=0;
data.forEach(function(e){
arr.push(e);
});
}
but i want to know can it be improved or is there more native way.
The Array.prototype.splice() function is what you are looking for, this is your way to go:
function putDataInThis(arr) {
var data = [3, 4, 6, 2, 6, 1];
arr.length = 0;
arr.splice(0, arr.length, data);
return arr;
}
alert(putDataInThis(["h", "g"]).join(","));
Explantation:
In the following arr.splice(0, arr.length, data) statement, we used splice() function with the following parameters:
0 the beginning index for the replacement.
arr.length as the number of elements to replace.
And data is the list of new values to put in our array.
Read Array.splice( ): insert, remove, or replace array elements for further information.
I think you could use jquery merge.
function putDatainthis(arr) {
var data = [3,4,6,2,6,1];
$.merge(arr, data);
}
Try this way.
function putDatainthis(arr) {
var data = [3,4,6,2,6,1];
var concat_array = data.concat(arr);
}

Problems with Javascript function [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I need to understand this code. It made for a ex-developer in my company, but really I don't understand so well how it works... If someone could help me, I will apreciate it.
var main= function(arr, fun) {
var i= 0,
max= arr.length,
array= [];
for (; i< max; i++) {
array.push(fun(arr[i]));
}
return array;
};
It's essentially a very obscure Array.prototype.map implementation. Personally I'd suggest this:
function array_map(arr,callback) {
if( arr.map) return arr.map(callback);
for( var i=0, l=arr.length, ret = []; i<l; i++) {
ret[i] = callback(arr[i],i,arr);
}
return ret;
}
It uses the browser's built-in function if it exists, and manually simulates it otherwise.
Maybe you can understand it well if you treat the argument "fun" as a function name. Your code just return the result of array "arr" after running as the "fun"'s input argument.
As following shows:
var arr = [0, 1, 2];
function fun( arg ) {
return arg + 1;
}
In my mind, call your code like this:
main(arr, fun);
It should return:
[1, 2, 3]
Of course, I have not check it if it's really correct, you may take a test~
good luck
var main= function(arr, fun) {
//intialing variables
var i= 0,
max= arr.length,
array= [];
//looping the variables
for (; i< max; i++) {
//push values in to array after using the function passed
array.push(fun(arr[i]));
}
return array;
};
//to test I have defined a function which adds 1
var res = main([1,2,3], function(val) {return val + 1});
alert(res);
Fiddle
var main = function(arr, fun) {
var i = 0, //starting a loop through the array at 0
max = arr.length, //getting the number of items in the array
array= []; //declaring a new array
for (; i< max; i++) { //this is a loop that goes through all the values in the array
array.push(fun(arr[i])); //this adds the values to the new array, using the function 'fun' to change the value
}
return array; //this returns the array
};
It creates a new array by putting the results from a previous array arr for a function fun into the new array.
For instance, if fun gets the square of a number and arr is [1, 2, 3], main will return [1, 4, 9]
It creates a function called main. This function takes an array and a handler function fun as parameters. It provides each element of the array to fun function and it adds the result of this call (fun(arr[i])) to a new array. For example, the following use of the main function returns an array {2, 3, 4, 5}.
main({1, 2, 3, 4}, function(item) {
return item + 1;
});
Let's split the code:
// will create a function which accepts 2 parameters
var main= function(arr, fun) {
//variable declaration
var i= 0,
max= arr.length, // get array length
array= []; // create new array
// add function value (fun(arr[i])) to an array. arr is a parameter which is also an array
// fun(arr[i]) is a callback function which accepts 1 parameter (array one)
for (; i< max; i++) {
array.push(fun(arr[i]));
}
// return the new array
return array;
};
You need a strategy for dealing with unfamiliar constructs. Asking a blanket question on Stackoverflow may help in the short term, but probably doesn't strengthen your interpretation "muscles".
I'd suggest first ensuring that you can run the code in a debugger and set a breakpoint at the first line of code in the function. Then use the debugger to answer questions such as:
1). What comes in? What are the types of the arguments.
2). What is returned
You then notice that fun is actually a function. So from where is your function called? What functions are passed as that second argument.
You might then be wondering about some construct you've not seen before, for example what array.push() does. So a quick google answers that.
Suddenly you understand and have exercised you "muscles". And if you are still confused you probably have a much better, more precise question to ask here.

creating multi-dim arrays (JS)

I was trying to create a 3-dimensional array and couldn't find an easy way to do it.
array = [[[]]];
or
array = [][][];
or
array = []; array[] = []; array[][] = [];
would for example not work. (the console'd say the second array is 'undefined' and not an object, or for the second and third example give a parse error).
I cannot hard-code the information either, as I have no idea what the indexes and contents of the array are going to be (they are created 'on the fly' and depending on the input of a user. eg the first array might have the index 4192). I may have to create every array before assigning them, but it would be so much easier and faster if there's an easier way to define 3-dimensional arrays. (there'll be about 2 arrays, 25 subarrays and 800 subsubarrays total) every millisecond saves a life, so to say.
help please?
JavaScript is dynamically typed. Just store arrays in an array.
function loadRow() {
return [1, 2, 3];
}
var array = [];
array.push(loadRow());
array.push(loadRow());
console.log(array[1][2]); // prints 3
Since arrays in javascript aren't true arrays, there isn't really a multidimensional array. In javascript, you just have an arrays within an array. You can define the array statically like this:
var a = [
[1,2,3],
[4,5,6],
[7,8,9]
];
Or dynamically like this:
var d = [];
var d_length = 10;
for (var i = 0;i<d_length;i++) {
d[i] = [];
}
UPDATE
You could also use some helper functions:
function ensureDimensions(arr,i,j,k) {
if(!arr[i]) {
arr[i] = [];
}
if(!arr[i][j]) {
arr[i][j] = [];
}
}
function getValue(arr,i,j,k) {
ensureDimensions(i,j,k);
return arr[i][j][k];
}
function setValue(arr,newVal,i,j,k) {
ensureDimensions(i,j,k);
arr[i][j][k] = newVal;
}

Categories