10

I have an associative array object in Javascript that I need only part of. With a regular array, I would just use slice to get the part I need, but obviously this won't work on an associative array. Is there any built in Javascript functions that I could use to return only part of this object? If not, what would be considered best practices for doing so? Thanks!

David Savage
  • 1,562
  • 2
  • 18
  • 35
  • Firstly, tell us about the type of data you store in it and what you need to do with it. Is it multidimensional? Does it need to be ordered? Several details about the specific needs would be helpful. – meder omuraliev Dec 09 '10 at 17:16
  • Yes, I am using jQuery throughout this site. – David Savage Dec 09 '10 at 17:16
  • @meder: basically I have a list of options in a faceted navigation that I am storing the user's preferences on. So, its basically a list of checkboxes that are either checked or not, and I'm trying to keep those values remembered. However, this associative array also contains other information related to the page, so I only need part of it. I'm using an associative array so the keys can be used to reference the id of the checkbox. – David Savage Dec 09 '10 at 17:18
  • 1
    @Ivo: sorry, I'm a newb when it comes to proper terminology :P – David Savage Dec 09 '10 at 17:18

3 Answers3

4

There's not going to be a good way to 'slice' the Object, no, but you could do this if you really had to:

var myFields = ['field1', 'field2', 'field3'];

var mySlice = {};

for (var i in myFields) {
  var field = myFields[i];

  mySlice[field] = myOriginal[field];
}
g.d.d.c
  • 46,865
  • 9
  • 101
  • 111
  • 3
    Missing hasOwnProperty... explodes in 3...2...1... ;) – Ivo Wetzel Dec 09 '10 at 17:19
  • Hmm, so basically I just have to loop through the object properties? Since my object has all the properties I need in the sliced object together, couldn't I just increment an int while looping and only get the numbers I need? i.e. if (i > 0 && i < 11)? – David Savage Dec 09 '10 at 17:25
  • 1
    @IvoWetzel If there's code on the page that adds enumerable properties on the Object prototype then it's their own damn fault! – Raynos Dec 09 '10 at 17:26
  • @Raynos What about poor people using Prototype? :P – Ivo Wetzel Dec 09 '10 at 17:27
  • @David Savage - Essentially, yes, you loop over the ones you know you need and add them to your 'slice'. You can certainly loop while incrementing an int, but depending on the size of your original object you may end up with performance penalties (if you have 1000 items to check and need 10 you're performing 990 extra checks). If they're conveniently arranged you could break the loop early to avoid some of that penalty. – g.d.d.c Dec 09 '10 at 17:34
  • @David, g.d.d.c: Don't do `for/in` over an Array. It is a useful practice to prototype Array with additional methods when needed, and `for/in` will pick those up. Better to use a traditional `for` loop. – user113716 Dec 09 '10 at 17:53
2

There is small function I use:

/**
 * Slices the object. Note that returns a new spliced object,
 * e.g. do not modifies original object. Also note that that sliced elements
 * are sorted alphabetically by object property name.
 */
function slice(obj, start, end) {

    var sliced = {};
    var i = 0;
    for (var k in obj) {
        if (i >= start && i < end)
            sliced[k] = obj[k];

        i++;
    }

    return sliced;
}
pleerock
  • 18,322
  • 16
  • 103
  • 128
2

I've created this gist that does exactly this. It returns a new object with only the arguments provided, and leaves the old object intact.

if(!Object.prototype.slice){
    Object.prototype.slice = function(){
        var returnObj = {};
        for(var i = 0, j = arguments.length; i < j; i++){
            if(this.hasOwnProperty(arguments[i])){
                returnObj[arguments[i]] = this[arguments[i]];
            }
        }
        return returnObj;
    }
}

Usage:

var obj = { foo: 1, bar: 2 };

obj.slice('foo'); // => { foo: 1 }
obj.slice('bar'); // => { bar: 2 }
obj;              // => { foo: 1, bar: 2 }
zykadelic
  • 1,083
  • 11
  • 19