0

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!

2
  • There is only one occurrene of Jon... Why would he get flagged? Janes cat is the last occurrence... wouldnt that get flagged B? Commented Dec 2, 2009 at 11:21
  • Sorry, I just realized the potential confusion here. The relevant criterion is the name of the picture, not the name of the owner. Will update, thanks. Commented Dec 2, 2009 at 11:29

2 Answers 2

1

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!

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

3 Comments

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.
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 :)
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.
1

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;
        }
    }
}

1 Comment

This is pretty close to what I had in mind originally - but I went with Kaze's solution (for now?). Thanks!

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.