2

I have an array of objects that I would like to break down into another set of arrays based on a property of the objects in the array.

For example, I have some object such as this:

function Object1(property1, property2, property3){
this.property1 = property1;
this.property2 = property2;
this.property3 = property3;
}

Then, I have an array with several of these objects, however some share the same value for property1, such as:

const obj1 = new Object1(id_1, some_value_1, some_value_2);
const obj2 = new Object1(id_2, some_value_2, some_value_2);
const obj3 = new Object1(id_1, some_value_3, some_value_3);
const obj4 = new Object1(id_2, some_value_4, some_value_4);

var objectArray = [obj1, obj2, obj3, obj4];

Now given this array, I want to create new arrays based on Object1.property1, so that I end up with the following arrays:

array1 = [obj1, obj3];
array2 = [obj2, obj4];

This is no doubt not much of a task but I can't think atm. Thanks for input.

There is a caveat or two: I won't always know how large the objectArray is, and I won't know how many objects within that array share a property, meaning need x number of new arrays.

2
  • What do you mean by "create new arrays based on Object1.property1" ?? Commented May 1, 2018 at 22:39
  • And how the new arrays are created? What is the criteria? Commented May 1, 2018 at 22:40

3 Answers 3

2

You can use reduce to group objects by a particular property:

function Object1(property1, property2, property3) {
  this.property1 = property1;
  this.property2 = property2;
  this.property3 = property3;
}

const obj1 = new Object1('id_1', 'some_value_1', 'some_value_2');
const obj2 = new Object1('id_2', 'some_value_2', 'some_value_2');
const obj3 = new Object1('id_1', 'some_value_3', 'some_value_3');
const obj4 = new Object1('id_2', 'some_value_4', 'some_value_4');

const objectArray = [obj1, obj2, obj3, obj4];

const outputObj = objectArray.reduce((accum, obj) => {
  const id = obj.property1;
  if (!accum[id]) accum[id] = [];
  accum[id].push(obj);
  return accum;
}, []);

const [array1, array2] = Object.values(outputObj);
console.log(array1);
console.log(array2);

You should also take care not to mix const and var - if you're going to use ES6, always use const (and rarely use let, when reassignment is necessary).

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

2 Comments

Proposal to save the if-condition: accum[id] = [...(accum[obj] || []), obj]
The .reduce call has definitely gotten me onto the right track I think, thank you.
1

For simplicity I'll create the array and objects inline.

This will be done in two passes. First, group the prop2 and prop3 by prop1. Then, filter out unique elements for each group.

var things = [
  {prop1: 1, prop2: 'a', prop3: 'b'},
  {prop1: 2, prop2: 'b', prop3: 'b'},
  {prop1: 1, prop2: 'c', prop3: 'c'},
  {prop1: 2, prop2: 'd', prop3: 'd'}
];

var grouped = things.reduce(function (groups, thing) {
  groups[thing.prop1] = groups[thing.prop1] || [];
  groups[thing.prop1].push(thing.prop2);
  groups[thing.prop1].push(thing.prop3);
  return groups;
}, {});

/*
We are now grouped by prop1.
{
1: ["a", "b", "c", "c"],
2: ["b", "b", "d", "d"]
}
*/

var groupedAndUniq = Object.keys(grouped).reduce(function (groups, key) {
  groups[key] = [...new Set(grouped[key])];
  return groups;
}, {});

console.log(groupedAndUniq);

/*
We are now grouped and unique.
{
1: ["a", "b", "c"],
2: ["b", "d"]
}
*/

2 Comments

Thank you for the advice. I don't want to separate the properties from the objects, I need the objects in tact.
The .reduce call has definitely gotten me onto the right track I think, thank you.
0

you can use .filter() to select objects in the array based on a property value :

function Object1(property1, property2, property3) {
  this.property1 = property1;
  this.property2 = property2;
  this.property3 = property3;
}

const obj1 = new Object1(1, 'a', 'A');
const obj2 = new Object1(2, 'b', 'B');
const obj3 = new Object1(1, 'c', 'C');
const obj4 = new Object1(2, 'd', 'D');

const objectArray = [obj1, obj2, obj3, obj4];

const array1 = objectArray.filter(e => e.property1 == 1)
const array2 = objectArray.filter(e => e.property1 == 2)

console.log(array1)
console.log(array2)

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.