1

I have an array like this:

var records = [{
  "field1": "dogs",
  "field2": "poodle"
}, {
  "field1": "dogs",
  "field2": "alsatian"
}, {
  "field1": "dogs",
  "field2": "chowchow"
}, {
  "field1": "dogs",
  "field2": "schnauzer"
}, {
  "field1": "cats",
  "field2": "siamese"
}, {
  "field1": "cats",
  "field2": "persian"
}, {
  "field1": "fish",
  "field2": "guppy"
}, {
  "field1": "fish",
  "field2": "tiger barb"
}]

I want to iterate over the array and create a new array Pets, so that I can access it like

var Pets = [{
  "type": "dogs",
  "breeds": ["poodle", "alsatian", "chowchow", "schnauzer"]
}, {
  "type": "cats",
  "breeds": ["siamese", "persian"]
}, {
  "type": "fish",
  "breeds": ["guppy", "tiger barb"]
}]

I tried to do a for loop but it doesn't work as I use i+1 in an array like so

var thispet = {};
var Pets = [];

thispet.type = records[0].field1;
Pets.push(thispet);

for (i = 1; i < records.length; i++) {
  if (Pets[i - 1].type != records[i].field1) {
    thispet.type = records[i] field1;
    Pets.push(thispet);
  }
}

But somehow the Pets[i-1].type is not recognised as object.

I wanted to first create 3 objects in array Pets based on the 3 types of pets in the records, then sort out the second order of breeds(should be easier with push into array. I have a large record, so a loop will help greatly.

Seth
  • 10,198
  • 10
  • 45
  • 68
Ben Looi
  • 178
  • 2
  • 9

2 Answers2

2

It would be much simpler to group the pets by type first and then reformat the result into an array:

var group, pets = [], groups = {};
for (var i = 0; i < records.length; ++i) {
    group = groups[records[i].field1] || groups[records[i].field1] = [];
    group.push(records[i].field2);
}

for (var type in groups) {
    if (!groups.hasOwnProperty(type)) continue; // just to be on the safe side
    pets.push({ type: type, breeds: groups[type] });
}

The .hasOwnProperty check is standard procedure to avoid unpleasant surprises from third party code.

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
2

A possible solution in ECMA5.

var records = [{
        "field1": "dogs",
        "field2": "poodle"
    }, {
        "field1": "dogs",
        "field2": "alsatian"
    }, {
        "field1": "dogs",
        "field2": "chowchow"
    }, {
        "field1": "dogs",
        "field2": "schnauzer"
    }, {
        "field1": "cats",
        "field2": "siamese"
    }, {
        "field1": "cats",
        "field2": "persian"
    }, {
        "field1": "fish",
        "field2": "guppy"
    }, {
        "field1": "fish",
        "field2": "tiger barb"
    }],

    x = records.reduce(function (acc, record) {
        if (!acc[record.field1]) {
            acc[record.field1] = [];
        }

        if (acc[record.field1].indexOf(record.field2) === -1) {
            acc[record.field1].push(record.field2);
        }

        return acc;
    }, {}),

    y = Object.keys(x).map(function (key) {
        return {
            type: key,
            breeds: this[key]
        };
    }, x);

document.getElementById('out').textContent = JSON.stringify(y, null, 2);
<pre id="out"></pre>
Xotic750
  • 22,914
  • 8
  • 57
  • 79