-1

Given the following json object:

var posts = {
    [0] : {
        "name": "X",
        "categories" : [1, 5, 6]
    },
    [1] : {
        "name": "Y",
        "categories" : [1, 5, 7]
    }
}

How can I get a single array containing every "categories" property value, without repetitions?

In this case, I would like to retrieve something like

var objCategories = [1, 5, 6, 7];

João Colucas
  • 249
  • 1
  • 3
  • 14
  • Please learn the difference between [objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer) and [arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array). Your definition of `posts` is very strange. – str Oct 10 '17 at 09:09
  • I'm voting to close this question as off-topic because the question shows input and output format but not any sign of effort. This makes question a requirement and not a problem statement – Rajesh Oct 10 '17 at 09:11
  • You can refer to following links: **[Group based on property](https://stackoverflow.com/questions/31688459/group-array-items-using-object)** and **[Remove duplicates from array](https://stackoverflow.com/questions/9229645/remove-duplicates-from-javascript-array)** and play around(*merge*) to get the final solution. – Rajesh Oct 10 '17 at 09:13

5 Answers5

1

In a ES6 enabled environment, you can use a Set and reduce

let objCategories = [...new Set(Object.values(posts).reduce((a,b) => a.concat(b.categories), []))];

let posts = {
  [0]: {
    "name": "X",
    "categories": [1, 5, 6]
  },
  [1]: {
    "name": "Y",
    "categories": [1, 5, 7]
  }
};
let cats = [...new Set(Object.values(posts).reduce((a, b) => a.concat(b.categories), []))];
console.log(cats);
baao
  • 71,625
  • 17
  • 143
  • 203
0

something like

var objCategories = {}; //create a map for all unique keys
Object.keys(posts).forEach( function(index){
  var post = posts[ index ]; //get access to the object
  post.categories.forEach( function(cat){
    objCategories[ cat ] = cat;  
  });
});
objCategories = Object.keys( objCategories ); //get only the arrays of categories and assign them back to objCategories for desired result
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
0

do

var posts = {
    [0] : {
        "name": "X",
        "categories" : [1, 5, 6]
    },
    [1] : {
        "name": "Y",
        "categories" : [1, 5, 7]
    }
}

// logic
var merged = []; // get all of the categories
for (let name in posts) { // loop through name
  var post = posts[name]; // get post
  merged = merged.concat(post.categories); // add categories
}
var unique = merged.filter(function(item, pos, self) { // filter duplicates
    return self.indexOf(item) == pos;
});
console.log(unique);

exp:

this gathers all the categories

for (let name in posts) { // loop through name
  var post = posts[name]; // get post
  merged = merged.concat(post.categories); // add categories
}

the result will be

[1, 5, 6, 1, 5, 7]

then this filters out the duplicates:

var unique = merged.filter(function(item, pos, self) { // filter duplicates
    return self.indexOf(item) == pos;
});

the result is"

[1, 5, 6, 7]
notrota
  • 1,048
  • 10
  • 21
  • what? it solves the question - he asked to find all the unique categories – notrota Oct 10 '17 at 09:17
  • My point was about your explanation. *do* does not explain what and why are you doing what you are doing. You are answering for readers and not just OP. – Rajesh Oct 10 '17 at 09:18
0

You have to loop through the object:

var posts = {
    [0] : {
        "name": "X",
        "categories" : [1, 5, 6]
    },
    [1] : {
        "name": "Y",
        "categories" : [1, 5, 7]
    }
}
var objCategories = [];

Object.values(posts).forEach(post => { 
    post.categories.forEach(c => {
        if (objCategories.indexOf(c) === -1) {
            objCategories.push(c);
        }
    })
});

console.log(objCategories);
Faly
  • 13,291
  • 2
  • 19
  • 37
0

Use reduce and forEach:

var posts = {
    [0] : {
        "name": "X",
        "categories" : [1, 5, 6]
    },
    [1] : {
        "name": "Y",
        "categories" : [1, 5, 7]
    }
};

var result = Object.keys(posts).reduce(function (categories, key) {
  posts[key].categories.forEach(function (category) {
    if (categories.indexOf(category) === -1) {
      categories.push(category);
    }
  });
  return categories;
}, []);

console.log(result);
Andrzej Smyk
  • 1,684
  • 11
  • 21