1

I have an array of objects, shown below. The first segment of code is within a loop where multiple objects of 'Item' are created and pushed onto the array.

Example of the problem is available here: http://jsfiddle.net/X6VML/
Notice how changing the value inside a textbox displays a duplicate item.

 // class
 var Item = function(label, value) {
    this.Label = label;
    this.Value = value;
 };

 var obj = new Item("My Label", "My Value");

 // adds object onto array
 itemArray.push(obj);

The problem I have is that the array can contain duplicate objects which I need to filter out before rending the list of objects into a table, shown below:

  for (var i = 0; i < itemArray.length; i++) {
      $('.MyTable').append("<tr><td>" + itemArray[i].Label + "</td><td>" + itemArray[i].Value + "</td></tr>");
  }

I can identify whether it's a duplicate with the Value being the same. How can I filter the list of objects based on whether the Value already exists in the array?

Many thanks

4 Answers 4

1

Just don't add duplicate item in array:

var item = new Item("My Label", "My Value1");

if(!$.grep(itemArray, function(obj) { return obj.Value == item.Value; }).length)
  itemArray.push(item);

If there is already an object with Value "My Value1" in itemArray, just don't add it.

Sign up to request clarification or add additional context in comments.

2 Comments

this would be ideal obviously.. Im sure this code is great but can you rewrite it perhaps so I can see what it's doing please? Thanks,
Check doc for $.grep() method api.jquery.com/jQuery.grep. Sorry i don't understand what you mean by 'so I can see what it's doing'??? BTW, if you provide relevant code as how you add new items in array it would be more usefull.
0

A simple solution would be:

var temp = [];
$.each(itemArray, function(index, obj){
    var found = false;
    $.each(temp, function(tempI, tempObj){
        if(tempObj.Value == obj.Value){
            found = true;
            return false;
        }
    });

    if(!found){
        temp.push(obj);
    }
});

itemArray = temp;
console.log(itemArray);

The above is simply iterating over each object in the array, and pushing it to the temp array if it's not already there, finally it overwrites itemArray with temp.


Have you considered eliminating duplicates at the point of adding to the array? Something like this:

function UniqueItemList(){
    var items = [];

    this.push = function(item){
        for(var i=0; i<items.length; i++){
            if(items[i].Value == item.Value){
                return;
            }
        }
        items.push(item);
    };

    this.getList = function(){
        return items;
    }
}

var myList = new UniqueItemList();

myList.push(new Item('label1', 'value1'));
myList.push(new Item('label2', 'value2'));
myList.push(new Item('label1', 'value1'));
myList.push(new Item('label1', 'value1'));

console.log(myList.getList());

If you try to push a duplicate item, it will be rejected.

Demo - here it is integrated into your code.

8 Comments

that would be ideal.. just looking at your suggestion
@JamesRadford see my edit - added a demo of it integrated into your code. jsfiddle.net/qPSpp/1
thanks but when I change a value it duplicates a echoed value? I need to update the original rather than a duplicated item. Hope thats clear..?
please see here, it's almost complete although with my modifications although I'm not sure whether to call .clear? temp-share.com/show/gFHKQRlzY
when I call 'clear' the list only shows 1 item.. -- because Clear() removes them obviously..
|
0

This code would do. Modify the itemArray before forming the HTML.

var arr = {};
for ( var i=0; i < itemArray.length; i++ )
    arr[itemArray[i].Value] = itemArray[i];
itemArray = new Array();
for ( key in arr )
    itemArray.push(arr[key]);

2 Comments

think its very close actually. Can you explain what it's doing please?
because the obj.value should be unique, a map is created with obj.value as key and obj as value. this eliminates the duplicate entries.
0

I've got this handy utility function:

function uniq(ary, key) {
    var seen = {};
    return ary.filter(function(elem) {
        var k = (key || String)(elem);
        return seen[k] === 1 ? 0 : (seen[k] = 1);
    })
}

where key is a function that fetches the comparison key from an element.

Applied to your use case:

uniqueItems = uniq(itemArray, function(item) { return item.Value })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.