Sign up ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I'm curious if this is the right way of going about the issue:

function sortWordsByIncorrectAnswers(array) {
    array = array.slice(0)
    var sortedArray = array.sort(function (a, b) {
        a = a.fields.false;
        b = b.fields.false;
        return a < b ? -1 : a > b ? 1 : 0;
    });
    return sortedArray
}

I want to return a new version of the array, and not change 'array' passed into the method (deep copy).

This works as I want it to, but is this the correct way of doing this? It seems off.

share|improve this question
    
You are making a shallow copy, not a deep copy. That means you get a new array, but if the elements in the array are objects or arrays themselves, then they are the same objects as in the first array (a shallow copy). A deep copy is usually done with a recursive algorithm that looks at the type of each element in the array to see if it is an object that needs to be copied. – jfriend00 Dec 30 '13 at 23:45
    
Doesn't array.slice(0) perform a deep copy? – Gregorio Di Stefano Dec 30 '13 at 23:51
    
No. array.slice(0) makes a shallow copy. It gives you a new array with all the same elements in it. That's the definition of a shallow copy. A deep copy would have all new elements in it too and if any of the elements in the array were arrays, those arrays would be copies too. – jfriend00 Dec 30 '13 at 23:52
1  
You can see this answer for how to make a deep copy: stackoverflow.com/a/728694/816620 – jfriend00 Dec 30 '13 at 23:58
    
Thank you very much – Gregorio Di Stefano Dec 31 '13 at 0:01

2 Answers 2

up vote 1 down vote accepted

.slice() does not actually do a deep copy, the easiest way to do a deep copy with simple objects is

array = JSON.parse( JSON.stringify( array ) )

Also, you can sort on a boolean in a simpler way:

function sortWordsByIncorrectAnswers(array)
{
  array =  JSON.parse( JSON.stringify( array || [] ) );
  return array.sort( function(a, b)
  {
    return a.fields.false - b.fields.false;
  });
}
share|improve this answer

First off, that's what jQuery.extend is for. Resig answered this one himself over at StackOverflow and has documentation for the deep copy.

However, you can never completely clone an object. There are corner cases where even jQuery.extend could not possibly handle. As the author of this answer suggests:

It will not be able to handle any JavaScript object, but it may be sufficient for many purposes as long as you don't assume that it will just work for anything you throw at it.

Also, to comment at @tomdemuyt's answer, I have tried that method once in cloning object. However, it falls short when the object has non-serializable objects, like Functions. I once had an array with 6-10k entries, each 4-5 deep. When I did the stringify-parse routine, memory usage of the browser rocketed.

I'd rather rethink the approach rather than resorting to deep copies or other complicated approaches. In your case, you needed to sort an array while not affecting the original array You only need a 1-level copy in that case, and slice should work just fine.

share|improve this answer
1  
I did mention simple objects ;) – konijn Dec 31 '13 at 4:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.