views:

79

answers:

2

After requesting some user pictures, I end up with an array like this:

[
    { label: "portrait", owner: "Jon" },
    { label: "house", owner: "Jim" },
    { label: "portrait", owner: "Jim" },
    { label: "portrait", owner: "Jane" },
    { label: "cat", owner: "Jane" }
]

I need to highlight items whose label occurs multiple times in the array (here: "portrait").

Ideally, there'd be one flag (A) for items whose label occurs again later in the array, and another flag (B) for the final occurrence (i.e. both Jon's and Jim's portraits are flagged A, while Jane's gets B).

Any help would be greatly appreciated!

+1  A: 

I'm not sure what you're trying to do, but maybe you just need to aggregate the data?

var data = [
    { name: "portrait", owner: "Jon" },
    { name: "house", owner: "Jim" },
    { name: "portrait", owner: "Jim" },
    { name: "portrait", owner: "Jane" },
    { name: "cat", owner: "Jane" }
];

var byName = {};

for (var i = 0, l = data.length; i < l; ++i) {
    if (!byName[data[i].name]){
        byName[data[i].name] = [];
    }
    byName[data[i].name].push(data[i].owner);
}

// byName == {portrait: ["Jon", "Jim", "Jane"], house: ["Jim"], cat: ["Jane"]}

var byOwner = {};

for (var i = 0, l = data.length; i < l; ++i) {
    if (!byOwner[data[i].owner]) {
        byOwner[data[i].owner] = [];
    }
    byOwner[data[i].owner].push(data[i].name);
}


Or maybe you like this better:

var data = [
    { name: "portrait", owner: "Jon" },
    { name: "house", owner: "Jim" },
    { name: "portrait", owner: "Jim" },
    { name: "portrait", owner: "Jane" },
    { name: "cat", owner: "Jane" }
];

var byName = [];

for (var i = 0, l = data.length; i < l; ++i) {
    var done = false;
    for (var j = 0, k = data.length; j < k; ++j) {
        if (byName[j] && byName[j].name == data[i].name) {
            byName[j].data.push(data[i].owner);
            done = true;
        }
    }
    if (!done) {
        byName.push({name: data[i].name, data: [data[i].owner]});
    }
}

/*
byName == [
    {name: "portrait", data: ["Jon", "Jim", "Jane"]},
    {name: "house", data: ["Jim"]},
    {name: "cat", data: ["Jane"]}
] */

Because posting random code is fun and you know it!

Kaze no Koe
Thanks - I ended up with something quite similar to this; indexing by name (`results[image.name].push(owner)`). Then I later flatten it, which is when I add the required flags.
AnC
Good to know that it worked for you :) I proposed this because it just seemed strange to flag members of an array rather than just reorder them. I'm curious, could you tell me why you need to flag them? If it's not a supersecret algorithm of course :)
Kaze no Koe
It basically boils down to the name/label being the unique identifier (think creating a ZIP file with all images, using label as filename) - so if you have multiple occurrences, such conflicts need to be highlighted.
AnC
Got it, thanks.
Kaze no Koe
+1  A: 

I'd suggest looping through the picture array and adding a flagged member to each object, depending if it's duplicate. See below for an example. It will assign anything with a duplicate with an 'A' and the last duplicate with a 'B'. Anything that is not a duplicate is not flagged.

var picture_array = [
        {label: 'portrait', owner: "Jon"},
        {label: 'house', owner: "Jim"},
        {label: 'portrait', owner: "Jim"},
        {label: 'portrait', owner: "Jane"},
        {label: 'cat', owner: "Jane"}
    ],
    length = picture_array.length;

//Loop through picture_array

for(var i = 0; i < length; i++) {
    var picture = picture_array[i],
        label = picture.label;

    //If picture has already been flagged, go the the next picture
    if (picture.flagged) {
       continue;
    }

    //Loop through rest of the array to compare duplicate labels
    var picture_a = picture;
    for(var j = i + 1; j < length; j++) {
        var picture_b = picture_array[j];

        //If picture_a matches picture_b then flag both of them appropriately
        if (picture_a.label == picture_b.label) {
            picture_a.flagged = 'A';
            picture_b.flagged = 'B';
            picture_a = picture_b;
        }
    }
}
MillsJROSS
This is pretty close to what I had in mind originally - but I went with Kaze's solution (for now?).Thanks!
AnC