1

Take this array:

[
  {"color": "blue","type": 1},
  {"color": "red","type": 1},
  {"color": "blue","type": 1},
  {"color": "green","type": 1},
  {"color": "green","type": 1},
  {"color": "red","type": 2},
  {"color": "red","type": 1},
  {"color": "green","type": 2},
  {"color": "red","type": 3},
];

How would I go about finding which "color" has a different "type" (than all other objects with the same "name") in the array?

I want to be able to loop through this array and create a second array that would look like this:

{red, green}

Notice blue is ommited because all of the objects with "color":"blue" have the same "type"

The closest I have gotten is this: https://jsfiddle.net/0wgjs5zh/ but it adds all colors into the array appended with the different types:

arr.forEach(function(item){
  if(newArr.hasOwnProperty(item.color+ '-' +item.type)) {
   // newArr[item.color+ '-' +item.type].push(item);
  }
  else {
    newArr[item.color+ '-' +item.type] = item;
  }
});

// RESULT
{blue-1, green-1, green-2, red-1, red-2, red-3}
3
  • you meant color not name, right? Commented May 25, 2016 at 14:49
  • Yes, I updated my question. Thanks Commented May 25, 2016 at 14:50
  • 1. Just to confirm, the resulting array is a set? It doesn't allow duplicates? 2. How do you establish the base type? In other words, would the result array for { blue: 1, blue: 2, blue: 2} and { blue: 2, blue: 1, blue: 1 } be the same? Or do you know 1 is the base type? Commented May 25, 2016 at 14:54

2 Answers 2

4

You may use two passes, one for the collection and one for generating the result array.

var array = [{ "color": "blue", "type": 1 }, { "color": "red", "type": 1 }, { "color": "blue", "type": 1 }, { "color": "green", "type": 1 }, { "color": "green", "type": 1 }, { "color": "red", "type": 2 }, { "color": "red", "type": 1 }, { "color": "green", "type": 2 }, { "color": "red", "type": 3 }, ],
    result,
    object = Object.create(null);

array.forEach(function (a) {
    object[a.color] = object[a.color] || {};
    object[a.color][a.type] = true;
});

result = Object.keys(object).filter(function (k) {
    return Object.keys(object[k]).length > 1;
});

console.log(result);

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

1 Comment

Exactly what I needed. Thanks for you quick response and clean code.
0

My solution would be like as follows

var cls = [
  {"color": "blue","type": 1},
  {"color": "red","type": 1},
  {"color": "blue","type": 1},
  {"color": "green","type": 1},
  {"color": "green","type": 1},
  {"color": "red","type": 2},
  {"color": "red","type": 1},
  {"color": "green","type": 2},
  {"color": "red","type": 3},
],

    map = cls.reduce((p,c) => (p[c.color] ? !~p[c.color].indexOf(c.type) && p[c.color].push(c.type)
                                          : p[c.color] = [c.type], p),{}),
 result = Object.keys(map).reduce((p,c) => map[c].length > 1 && p.concat(c) || p,[]);

console.log(result);

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.