Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 14 of 14
  1. #1
    New Coder
    Join Date
    Jul 2012
    Location
    Mexico
    Posts
    45
    Thanks
    9
    Thanked 0 Times in 0 Posts

    I think this array handling can be improved

    I created an array the usual way: var subtotal = new Array();, but I created elements using an index from another set of data, with several numbers as index, like this:

    Code:
    subtotal[360]="23.50"
    subtotal[459]="8"
    subtotal[825]="12.50"
    subtotal[15253]="17"
    and so on, so this means that from positions 0 to 359 the values are empty, and so are from 361 to 458, etc.

    I have two questions:

    1) Is this a good way to do this, or the empty positions are consuming extra memory?

    and

    2) Now I need to sum all the existent values, I guess that with a For loop would be the normal way, but I'm afraid that

    Code:
    var sum = new Number();sum=0;
    for (var i=0;i<subtotal.length;i++){
    sum=sum+subtotal[i];
    }
    won't make the job. Is there a way to sum all the existent values in an array? Or do you recommend any efficient way to accomplish the same?

    Note that the index numbers are "product ids", and I made it that way to address the content by those ids.

    Thanks in advance.

  • #2
    Regular Coder
    Join Date
    Mar 2006
    Posts
    728
    Thanks
    35
    Thanked 132 Times in 123 Posts
    //
    The array methods map and reduce do not apply their function arguments to undefined elements-

    Code:
    var subtotal= [];
    subtotal[360]= "23.50";
    subtotal[459]= "8";
    subtotal[825]= "12.50";
    subtotal[15253]= "17";
    subtotal.map(Number).reduce(function(a, b){
    	return a+b;
    }).toFixed(2);
    /* returned value: (String)
    61.00
    */


    If you need to support older(<IE8) browsers you need a shim for the advanced array functions-
    Code:
    Array.prototype.map= Array.prototype.map || function(fun, scope){
    	var T= this, L= T.length, A= Array(L), i= 0;
    	if(typeof fun== 'function'){
    		while(i<L){
    			if(i in T){
    				A[i]= fun.call(scope, T[i], i, T);
    			}
    			++i;
    		}
    		return A;
    	}
    }
    Array.prototype.reduce= Array.prototype.reduce || function(fun, temp, scope){
    	var T= this, i= 0, len= T.length, temp;
    	if(typeof fun=== 'function'){
    		if(temp== undefined) temp= T[i++];
    		while(i<len){
    			if(i in T) temp= fun.call(scope, temp, T[i], i, T);
    			i++;
    		}
    	}
    	return temp;
    }
    You could also use a 'tight' array of objects-

    Code:
    function Sub(i, amount){
    	this.index= i;
    	this.amount= Number(amount);
    }
    var subtotal= [
    	new Sub(360, "23.50"),
    	new Sub(459, "8"),
    	new Sub(825, "12.50"),
    	new Sub(15253, "17")
    ];
    var sum= 0;
    for(var i= 0, L= subtotal.length;i<L;i++){
    	sum+= subtotal[i].amount;
    }

    sum.toFixed(2)

    /* returned value: (String)
    61.00
    */

  • #3
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Code:
    var sum = new Number();sum=0;
    for (var i=0;i<subtotal.length;i++){
        sum=sum+subtotal[i];
    }
    compare this with:

    Code:
    for (item in subtototal) {
        sum = sum + subtotal[item];
    }
    Code:
    for (item in subtotal) {
        console.log(item, subtotal[item]);
    }
    
    Output: 
    360 23.50
    459 8
    825 12.50
    15253 17
    That is, JavaScript does not "fill in the gaps". Arrays are objects and the indices are attributes of the (array-)object.
    Last edited by AndrewGSW; 01-05-2013 at 04:24 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • Users who have thanked AndrewGSW for this post:

    juliushg (01-06-2013)

  • #4
    Regular Coder
    Join Date
    May 2012
    Location
    France
    Posts
    224
    Thanks
    0
    Thanked 32 Times in 30 Posts
    It' always possible to use an object to avoid to define a 15554 length array !

    Code:
    var subtotal= {};
    subtotal[360]= 23.50; // a number without " "!
    subtotal[459]= 8;
    subtotal[825]= 12.50;
    subtotal[15253]= 17;
    sum=0;
    for (i in subtotal) sum+=subtotal[i];
    alert(sum.toFixed(2));
    Last edited by 007julien; 01-05-2013 at 10:30 PM.

  • #5
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    An array is an object, but then so is a date.. and anything else for that matter

    Code:
    var subtotal= [];
    subtotal[360]= "23.50";
    subtotal[459]= "8";
    subtotal[825]= "12.50";
    subtotal[15253]= "17";
    
    subtotal.Santa = "Claus";
    console.log(subtotal.Santa, subtotal['Santa']); // Claus Claus
    
    subtotal.xmas = function () { alert('Ho! Ho!'); };
    subtotal.xmas();
    
    var dte = new Date();
    dte.season = "Winter";
    console.log(dte.season); // Winter
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #6
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    It' always possible to use an object to avoid to define a 15554 length array !
    The array does not have that number of elements. The .length will be reported as 15554, as this is one more than the largest index, but the actual length - the number of elements - is four - as my previous code confirmed:

    Code:
    for (item in subtotal) {
        console.log(item, subtotal[item]);
    }
    
    Output: 
    360 23.50
    459 8
    825 12.50
    15253 17
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #7
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Code:
    var newArray = [];
    newArray[12] = "whatever";
    newArray[50] = "hi";
    newArray[34] = "what";
    newArray['54'] = "Whoa!";
    alert(newArray.length); // 55
    alert(newArray['12']); // whatever
    for (item in newArray) {
        console.log(newArray[item]);
    }
    
    Output:
    whatever
    what
    hi
    Whoa!
    When we define array elements using a number [12] we are creating object-attributes, rather than indices. However, JavaScript realises that it is a number and uses it to re-order (but not necessarily physically..) all those elements that also have a number as attribute. Because JS is (very) loosely typed, it also recognises '12' as being a number, and so would order this element as well.

    When we use numbers as the attribute (index) JS compares it with all other numerical-indices, and uses the largest of these numbers plus one as the .length of the object/array.
    Last edited by AndrewGSW; 01-05-2013 at 11:07 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #8
    Regular Coder
    Join Date
    May 2012
    Location
    France
    Posts
    224
    Thanks
    0
    Thanked 32 Times in 30 Posts
    Try this to count the number of array elements !

    Code:
    var subtotal= [];
    subtotal[360]= "23.50";
    subtotal[459]= "8";
    subtotal[825]= "12.50";
    subtotal[15253]= "17";
    alert(subtotal.length+'\n'+subtotal)

  • #9
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Code:
    var subtotal= [];
    subtotal[36]= "23.50";
    subtotal[49]= "8";
    subtotal[23]= "12.50";
    //subtotal[15253]= "17";
    //console.log(subtotal.length+'\n'+subtotal)
    //console.log(subtotal); // undefined, undefined..
    console.log(subtotal[40] instanceof Object); // false
    // console.log(subtotal[40] instanceof undefined); // TypeError
    If something in JavaScript is not an Object then it does not exist.. because everything in JS, apart from primitives, is an instance of Object.

    But I recall having this discussion before: I don't think it will lead to a conclusion

    [Did IE used to reserve space..? I can't recall.]
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #10
    New Coder
    Join Date
    Jul 2012
    Location
    Mexico
    Posts
    45
    Thanks
    9
    Thanked 0 Times in 0 Posts

    Thumbs up

    Thanks to all!

    Andrew, I'm not so experienced and didn't know the for (item in subtotal) but that did the trick. And yes, there are only those items in the array, not 15253 or whatever the highest index is, but that makes me think... then how "lenght" works? I always thought the lenght method reported the total of "occupied cells" in an array.

  • #11
    Regular Coder
    Join Date
    May 2012
    Location
    France
    Posts
    224
    Thanks
    0
    Thanked 32 Times in 30 Posts
    Null is not an object. It exists like subtotal[100] which is undefined !
    Last edited by 007julien; 01-06-2013 at 09:29 AM.

  • #12
    New Coder
    Join Date
    Jul 2012
    Location
    Mexico
    Posts
    45
    Thanks
    9
    Thanked 0 Times in 0 Posts
    Oh, now I see the explanation for what I asked about lenght in Andrew's fourth post.

  • #13
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Quote Originally Posted by 007julien View Post
    Null is not an object. It exists like subtotal[100] which is undefined !
    Code:
    alert(typeof null); // object
    But this conversation will lead no where: it is undefined.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #14
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,375
    Thanks
    11
    Thanked 592 Times in 572 Posts
    Quote Originally Posted by juliushg View Post
    Thanks to all!

    Andrew, I'm not so experienced and didn't know the for (item in subtotal) but that did the trick. And yes, there are only those items in the array, not 15253 or whatever the highest index is, but that makes me think... then how "lenght" works? I always thought the lenght method reported the total of "occupied cells" in an array.
    no, length is the highest index of the array, not the filled slots. this allows for arrays to be pre-allocated. compare with VB's ubound() function.

    since js is scripted, this is more of a wink and nod to traditional programming than anything, although it does allow bounds checking, and a very simple and fast way to empty an array by setting length to zero.

    null is indeed an object, and it is not undefined. i suggest reading the spec for the gruesome details.
    just know that like 0, false, and undefined, Boolean(null) is false.

    null doesn't come up very often, but when it does, it's usually used by the DOM to differentiate between something that doesn't exist like document.click (undefined) versus something that's uninitiated, like document.onclick (null)


    one trick for counting "populated" elements is by using Object.keys():


    Code:
    var subtotal= [1,2,3]; // 3 elements
    
    subtotal[360]= "23.50"; // add a fourth element
    
    subtotal[365]= null; // add a fifth element (note that null is not undefined)
    
    Object.keys(subtotal).length // === 5
    Last edited by rnd me; 01-07-2013 at 10:13 AM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •