HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Implementation of a unique collection

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
implementationuniquecollection

Problem

I am pretty new to JavaScript and learning the intricacies of this language. I wanted a unique collection which will overwrite while adding if an item already exists else add. Rest of the behavior should be just like any other collection. I had written the type and its as below. Instead of using an array internally, I have used JavaScript's notion of storing an object as key-value pair to store the items.

My question is, is this implementation valid? Are there any disadvantage with this implementation over using an array internally to hold the collection items instead of an object?

Why I chose objects to store items over array is:

  • To avoid iterating through the array while adding an item, so that I don't have to check if objects exists(instead of adding a duplicate).



  • To avoid iterating while retrieving or deleting an item.



```
function isValid(obj) {
return (obj != undefined && obj != null && typeof (obj) != 'undefined');
}

function uniqueCollection() {
var collection = {};
var length = 0;
return {
removeItem: function (item) {
if (isValid(collection[item])) {
delete collection[item];
--length;
}
},
addItem: function (item) {
if (!isValid(collection[item])) {
collection[item] = item;
++length;
}
},
getLength: function () {
return length;
},
clear: function () {
collection = {};
length = 0;
},
exists: function (item) {
if (isValid(collection[item])) {
return true;
}
return false;
},
getItems: function () {
var items = [];
var i = 0;
for (var o in collection) {
if (collection.hasOwnProperty(o)) {
items[i] = o.toString();
i++;
}
}

Solution

This mostly seems like a layer of sugar coating that just adds overhead and doesn't add any improved functionality over what a javascript object already has. The only new functionality I see is keeping track of a length, but this is a lot of extra overhead just for that. The length could be calculated at any time on a plain javascript object.

Here are the analogs to your methods:

var collection = {};

addItem:
    collection[key] = value;

removeItem: 
    delete collection[key]

clear:
    collection = {};

exists:
    if (key in collection)

getItems:
    collection.keys()

getLength:
    collection.keys().length


So, all you're getting out of your implementation is a slightly more efficient length and every other operation is less efficient than just using the native code way of doing it. Is this collection really useful?

There are some older browsers that don't offer the .keys() method, but there's a pretty simple shim that implements it if not available.

In addition, your implementation loses functionality that a plain javascript object has. For example, you can't pass your collection to any function that expects a javascript object with the keys and values on it because those are hidden inside, they aren't actually properties of the collection object itself. Then further, you can't do custom iteration of the keys and values without first creating an array of all the keys because you've hidden the natural ability to iterate the keys of a javascript object.

Code Snippets

var collection = {};

addItem:
    collection[key] = value;

removeItem: 
    delete collection[key]

clear:
    collection = {};

exists:
    if (key in collection)

getItems:
    collection.keys()

getLength:
    collection.keys().length

Context

StackExchange Code Review Q#7983, answer score: 7

Revisions (0)

No revisions yet.