0

I am trying to extract one element from an array 'shapes' where that element's id is equal to dragID. I want to know if i'm doing it the right way... lots of problems are arising in this, like, sometimes some elements gets skipped while pushing them back to real array from reserve array. Kindly tell me if there is a better way to do it..

 var reserveShapes = [];
    while(1)
    {
        drag = shapes.pop();
        if(drag.id == dragID)
        {
             break;
        }
        reserveShapes.push(drag);   
    }

    //alert(reserveShapes.length);
    for(var j=0; j<reserveShapes.length; j++)
    {
        ar temp = reserveShapes.pop();
        shapes.push(temp);
    }
Abdul Jabbar
  • 2,573
  • 5
  • 23
  • 43
  • Related: [How to find first element of array matching a boolean condition in JavaScript?](http://stackoverflow.com/questions/10457264/how-to-find-first-element-of-array-matching-a-boolean-condition-in-javascript) (but this doesn't remove the item, if that's what you want) – apsillers Nov 05 '13 at 19:04

2 Answers2

3

Wow. Your idea may work, but there's a much cleaner way:

var drag;
for (int i = 0; i < shapes.length; i++) {
    if (shapes[i].id == dragID) {
         drag = shapes[i];
         break;
    }
}

if (drag) {
    // a matching shape was found
    // ...
}

If you want to remove that element from its position in the array, use splice:

    if (shapes[i].id == dragID) {
        drag = shapes.splice(i, 1);
        break;
    }    

You definitely don't have to use push and pop to go through an array.

EDIT References showing you can access an array using []

The reading is kind of dense, but the specification for ECMA-262 (the latest standard to which JavaScript subscribes) is at http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf. On page 67, it says:

Properties are accessed by name, using either the dot notation: 
    MemberExpression . IdentifierName 
    CallExpression . IdentifierName 
or the bracket notation: 
    MemberExpression [ Expression ] 
    CallExpression [ Expression ]

The [] accessor is actually allowed on all objects, and arrays are special objects. Page 122 defines an array:

Array objects give special treatment to a certain class of property names. A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2^ 32 - 1. A property whose property name is an array index is also called an element. Every Array object has a length property whose value is always a nonnegative integer less than 2^ 32.

What this boils down to is "if you use numbers as indices to the properties of an object, that object is treated as an array."

The spec is fairly dense to read, so here are some easier references to using arrays in JavaScript:

Scott Mermelstein
  • 15,174
  • 4
  • 48
  • 76
  • I wish it was that easy but it's JavaScript, NOT C++.... you can't access an element like [i] in JavaScript :/ – Abdul Jabbar Nov 05 '13 at 19:06
  • 4
    @AbdulJabbar Sure you can. What makes you think you can't?? – Scott Mermelstein Nov 05 '13 at 19:07
  • 1
    Damn. Sorry, i'm new to JavaScript.... never really tried accessing an element like that. Had my mind set that its only possible through push and pop. Thanks for enhancing my knowledge. Much appreciated. Your code works fine! – Abdul Jabbar Nov 05 '13 at 19:24
  • @AbdulJabbar To be fair, I was under the same misconception for a while when I first started. But JavaScript (and ECMAScript) is intended to not be horrible to use, so "normal" array access makes sense. – Scott Mermelstein Nov 05 '13 at 19:25
1

A slightly more modern method from ECMAScript 5:

var drag;
shapes = shapes.filter( function (current) {
    if( current.id === dragID ) {
        drag = current;
        return false;
    }

    return true;
} );

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Ingo Bürk
  • 19,263
  • 6
  • 66
  • 100
  • I was considering this, but the matching value is removed from the array, but is no longer usable by subsequent code. – Scott Mermelstein Nov 05 '13 at 19:05
  • He didn't say he wanted to keep the cut off element, and if he did, it could still be done with `filter`. Also, he never said the id is unique. – Ingo Bürk Nov 05 '13 at 19:07
  • My bad (Although it was clear from code). I need to store the matching object in the drag object.. and also, id is unique! – Abdul Jabbar Nov 05 '13 at 19:07
  • Oddly enough, if I had to do it, I'd probably go with the loop – just a habit. It's always good to have different solutions for a problem. – Ingo Bürk Nov 05 '13 at 19:12
  • Worked like a charm... I knew there must be an easier, more simplified way of doing this. Thanks a tons! – Abdul Jabbar Nov 05 '13 at 19:15
  • 1
    Glad to have helped. Please do look at @ScottMermelstein's answer, though, as he clarifies an apparent misunderstanding regarding arrays. – Ingo Bürk Nov 05 '13 at 19:15
  • Just for the clarification, when the function returns false it means that the array has been filtered and in case of true it means that filter condition couldn't be applied?? – Abdul Jabbar Nov 05 '13 at 19:17
  • 1
    Please refer to the documentation I linked to. In short words, `true` signals to keep the element, `false` signals to throw the element away. `filter` returns the array with all elements where the function returned `true`. – Ingo Bürk Nov 05 '13 at 19:27