1

I'm trying to form a list from json data, see the example What I want is that it will show me the value just once when duplicate values occurs (2x Martini glass, I want it to return just one in the list), but leaves the array as is, i.e. still want to be able to hold all values in the array.

There'd sure be a simple way to achieve this, but i'm not finding it...

var data = {
    "cocktails": [{
        "name": "Bloody Mary",
            "glass": "longdrink",
            "ingredients": {
            "main": "vodka",
                "secondary": "tomato juice",
                "addition": "tabasco"
        }
    }, {
        "name": "Daiquiri",
            "glass": "martini glass",
            "ingredients": {
            "main": "white rum",
                "secondary": "lime juice",
                "addition": "sugar syrup"
        }
    }, {
        "name": "Martini",
            "glass": "martini glass",
            "ingredients": {
            "main": "gin",
                "secondary": "vermout",
                "addition": "olive"
        }
    }]
}

$(data.cocktails).each(function () {
    var output = "<ul><li>" + this.glass + "</li></ul>";
    $('#placeholder').append(output);
});
Tushar Gupta - curioustushar
  • 58,085
  • 24
  • 103
  • 107
Feddman
  • 86
  • 5
  • 1
    Create an array that stores each glass, and test if this.glass equals to a value of this array ? That's how I would do it, but there's surely a better way. – enguerranws Feb 11 '14 at 13:03
  • 1
    Duplicates on what levels? Just `glass`? Also, why are you passing the array to the jQuery function. I suggest `$.each()` – Johan Feb 11 '14 at 13:04
  • in this example yes, just on the glass values. – Feddman Feb 11 '14 at 13:05
  • And you want to remove the `glass` property in this case? – Johan Feb 11 '14 at 13:06
  • Johan, why would you suggest $.each() please? what's the actual difference? – Feddman Feb 11 '14 at 13:06
  • `$().each()` is most commonly used on a selector that returns DOM elements, or a collection of DOM elements. `$.each()` is used to iterate arrays. At least that's how I use them... – Johan Feb 11 '14 at 13:08
  • I do not want to remove the glass property on the array, I just want it to show up once in the list, even if there are more arrays with the same value of glass. – Feddman Feb 11 '14 at 13:11
  • But I still need the actual info on how many of the same values exists in the array, so I can store this value in a bubble counter next to the list item for example. I hope i'm making sense... – Feddman Feb 11 '14 at 13:12

4 Answers4

0

Create an empty array:

var glasses = [];

Push all the glasses to it.

data.cocktails.forEach(function (el) {
  glasses.push(el.glass);
});

Create a deduped array of glasses. This leaves the glasses array intact so you can use it again.

var dedupedGlasses = glasses.filter(function(elem, pos) {
  return glasses.indexOf(elem) == pos;
});

Use join to create the HTML list.

var html = '<ul><li>' + dedupedGlasses.join('</li><li>') + '</li></ul>';

And add to the page.

$('#placeholder').append(html);

Demo

The you can use something like this to grab the count for each glasses type:

function getCount(arr) {
  return arr.reduce(function(m, e){
    m[e] = (+m[e]||0)+1; return m
  }, {});
}

console.log(getCount(glasses)); // { longdrink=1, martini glass=2 }
Community
  • 1
  • 1
Andy
  • 61,948
  • 13
  • 68
  • 95
  • You got here faster than me, though I used `map` instead of `forEach` - [jsFiddle](http://jsfiddle.net/Xotic750/Yj5aQ/) – Xotic750 Feb 11 '14 at 13:18
  • Awesome! will have to look inte the dedupedGlasses var to wrap my head around though... – Feddman Feb 11 '14 at 13:25
  • https://stackoverflow.com/questions/15711018/how-does-this-snippet-for-removing-duplicates-from-an-array-work – Andy Feb 11 '14 at 13:32
0

Basically the same as @Andy, though slightly different.

var data = {
    "cocktails": [{
        "name": "Bloody Mary",
            "glass": "longdrink",
            "ingredients": {
            "main": "vodka",
                "secondary": "tomato juice",
                "addition": "tabasco"
        }
    }, {
        "name": "Daiquiri",
            "glass": "martini glass",
            "ingredients": {
            "main": "white rum",
                "secondary": "lime juice",
                "addition": "sugar syrup"
        }
    }, {
        "name": "Martini",
            "glass": "martini glass",
            "ingredients": {
            "main": "gin",
                "secondary": "vermout",
                "addition": "olive"
        }
    }]
}

$('#placeholder').append('<ul><li>' + data.cocktails.map(function (cocktail) {
    return cocktail.glass;
}).filter(function (glass, index, array) {
    return array.indexOf(glass) === index;
}).join('</li><li>') + '</li></ul>');

On jsFiddle

Xotic750
  • 22,914
  • 8
  • 57
  • 79
0

I can just point to a solution where you need to define a new array

var cleanArr = []
$(data.cocktails).each(function () {
   if($.inArray(this.glass, cleanArr) === -1) cleanArr.push(this.glass);
   var output = "<ul><li>" + this.glass + "</li></ul>";
   $('#placeholder').append(output);

});
console.log(cleanArr)

I like the way the array is created, that's why I'm posting this solution but it is not my idea --> taken from: Remove Duplicates from JavaScript Array

Community
  • 1
  • 1
xhallix
  • 2,919
  • 5
  • 37
  • 55
0

Here is a working jsFiddle for you. http://jsfiddle.net/Q74pj/1/

And here is what I did:

I used a new function calling uniqueArray to create a new associative array (which would be the quickest to iterate and fill). You need to create a unique array, or sort it by drink and skip the duplicates.

function uniqueValues (arr) {
    //if (arr.length < 2) return arr;
    var retVal = {};
    for (var i = 0; i < arr.length; i++) {
        retVal[arr[i].glass] = arr[i];
    }

    return retVal;
}

then just use another way to iterate the associate array:

var uniqueArrayValues = uniqueValues(data.cocktails);
for (key in uniqueArrayValues) {
    var output = "<ul><li>" + uniqueArrayValues[key].glass + "</li></ul>";
    $('#placeholder').append(output);
}
Dory Zidon
  • 10,497
  • 2
  • 25
  • 39