0

i have an array of objects, looking like this:

[
    {
        "label": "anystring",
        "processowner": ["any name"],
        "withwhat": ["any text"],
        "withwho": ["any text"],
        "processstep": ["any text"],
        "cluster": ["anyValue1"]
    },
    {
        "label": "anystring",
        "processowner": ["any name"],
        "withwhat": ["any text"],
        "withwho": ["any text"],
        "processstep": ["any text"],
        "cluster": ["anyValue2"]
    },
    {
        "label": "anystring",
        "processowner": ["any name"],
        "withwhat": ["any text"],
        "withwho": ["any text"],
        "processstep": ["any text"],
        "cluster": ["anyValue1"]
    },
.........
]

The important Key, Value pair is "cluster". It is possible that there are more objects with the same '"cluster"'-Value. What i want is a new Array with just the "cluster"-Value. But each only once! That's were im struggling.

What i did so far is looping over the given array and compare the current "cluster"-Value with a second(final) array "tempNewJson" (second loop) - filled with the first object "initObj" of the given array in it. If the Value is already in "tempNewJson" i want the code to do nothing. If the Value is not yet in "tempNewJson" i want to add it. But i still get duplicates and a wrong number of Values in my final array "tempNewJson".

function convertJSON(initJson) {
var initObj = {};
initObj.title = initJson[0].cluster.toString();
initObj.scale = 6;
initObj.type = 'group-case-5-3';
initObj.children = [];
tempNewJson.push(initObj);
var contains = false;
// Schleife über alle Items in initialem JSON
for (var i = 0; i < initJson.length; i++) {
    // Schleife über bisher hinzugefügte Objekte in tempNewJSON
    contains = false;
     for(var j = 0; j < tempNewJson.length; j++) {
         contains = false;
         if(initJson[i].cluster.toString() === tempNewJson[j].title) {
             contains = true;
             console.log(initJson[i].cluster.toString());
             break;
         }
     }
     if(contains === false) {
            initObj.title = initJson[i].cluster.toString();
            console.log('test: ' + initJson[i].cluster.toString());
            tempNewJson.push(initObj);
     }
 }
}

Anyone knows how to fix this? Thanks.

The Output should look like this

["anyValue1", "anyValue2", .....]

I used Nina Scholz's answer like this:

var result = initJson.reduce(function (tempNewJson, initJson) {
    !~tempNewJson.indexOf(initJson.cluster) && tempNewJson.push(initJson.cluster.toString());
    return tempNewJson;
}, []);
 console.log(result);

What i get know ist the following array:

['anyValue1', 'anyValue2', 'anyValue1', 'anyValue3', 'anyValue1', .........

]

But what i want is:

['anyValue1', 'anyValue2', 'anyValue3', 'anyValue4', 'anyValue5', .........

]

5
  • I'm unclear on what the output should be; can you provide a sample? Commented Nov 2, 2015 at 16:02
  • I just updated my post @ExplosionPills Commented Nov 2, 2015 at 16:04
  • is cluster an array of strings? Commented Nov 2, 2015 at 16:11
  • if you use it !~tempNewJson.indexOf(initJson.cluster) && tempNewJson.push(initJson.cluster.toString()) this way, then you need a toString() also in the indexOf part like !~tempNewJson.indexOf(initJson.cluster.toString()) && tempNewJson.push(initJson.cluster.toString()) Commented Nov 2, 2015 at 16:55
  • 1
    Thanks! that did the trick!!! Commented Nov 2, 2015 at 16:59

4 Answers 4

1

If you can support it I would use a Set.

let set = new Set;
initObj.map(item =>
    item.cluster.map(cluster => set.add(cluster))
);

Now set is an iterable with unique cluster values.

Otherwise you can do this with an array, but you have to do the unicity check on your own:

let newArr = [];
initObj.map(item =>
    item.cluser.map(cluster => {
        if (-1 === newArr.indexOf(cluster)) {
            newArr.push(cluster);
        }
    });
);
Sign up to request clarification or add additional context in comments.

Comments

0

Simple solution with Array.prototype.reduce. The advantage of this method is the possibillity to return something (here an array) and take it as an input for the next iteration.

var array = [{
        "label": "anystring",
        "cluster": "anyValue1"
    }, {
        "label": "anystring",
        "cluster": "anyValue2"
    }, {
        "label": "anystring",
        "cluster": "anyValue1"
    }],
    result = array.reduce(function (r, a) {
        !~r.indexOf(a.cluster) && r.push(a.cluster);
        return r;
    }, []);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

3 Comments

This is short and works, but i still have duplicates in the result array.
@dnks23, please supply some more data.
tried to update my post above, does this help? dont know what else to provide.... @Nina Scholz
0

You can use map() and filter() for this.

var data = [
    {
        "label": "anystring",
        "processowner": ["any name"],
        "withwhat": ["any text"],
        "withwho": ["any text"],
        "processstep": ["any text"],
        "cluster": ["anyValue1"]
    },
    {
        "label": "anystring",
        "processowner": ["any name"],
        "withwhat": ["any text"],
        "withwho": ["any text"],
        "processstep": ["any text"],
        "cluster": ["anyValue2"]
    },
    {
        "label": "anystring",
        "processowner": ["any name"],
        "withwhat": ["any text"],
        "withwho": ["any text"],
        "processstep": ["any text"],
        "cluster": ["anyValue1"]
    }
];

var clusters = data.map(function(item) {
    return item.cluster[0];
});

clusters = clusters.filter(function(item, pos) {
    return clusters.indexOf(item) == pos;
})

console.log(clusters)

Comments

0

You can use pure JS to simply loop through your array and create a result object that contains all the objects with certain cluster keys, which creates a very useful object! The same thing is true for just getting your desired array of cluster names.

// Simplified test object without all the value
var test = [
  {"id": 1,"cluster": ["anyValue1"]},
  {"id": 2,"cluster": ["anyValue2"]},
  {"id": 3,"cluster": ["anyValue1"]}
];

var result = {};
for(var i = 0; i < test.length; i++){
  for(var c = 0; c < test[i].cluster.length; c++){
    result[test[i].cluster[c]] = result[test[i].cluster[c]] || [];
    result[test[i].cluster[c]].push(test[i]);
  }
}

document.write('<pre>');
document.write(JSON.stringify(result));

var result = [];
for(var i = 0; i < test.length; i++){
  for(var c = 0; c < test[i].cluster.length; c++){
    if(result.indexOf(test[i].cluster[c]) < 0)
      result.push(test[i].cluster[c])
  }
}

document.write('<br /><br />' + JSON.stringify(result));
document.write('</pre>');

Both objects could be very useful in their own way.

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.