Convert flat array of objects into nested array of objects












12















Original JSON data (flat table):



[
{"id":"1","first_name":"Jason","last_name":"Martin","start_date":"1996-07-25","end_date":"2006-07-25","salary":"1234.56","city":"Toronto","description":"Programmer","department":"Finance","active":"1"},
{"id":"2","first_name":"Alison","last_name":"Mathews","start_date":"1976-03-21","end_date":"1986-02-21","salary":"6661.78","city":"Vancouver","description":"Tester","department":"Finance","active":"1"},
{"id":"3","first_name":"James","last_name":"Smith","start_date":"1978-12-12","end_date":"1990-03-15","salary":"6544.78","city":"Vancouver","description":"Tester","department":"QA","active":"1"},
{"id":"4","first_name":"Celia","last_name":"Rice","start_date":"1982-10-24","end_date":"1999-04-21","salary":"2344.78","city":"Vancouver","description":"Manager","department":"HR","active":"1"},
{"id":"5","first_name":"Robert","last_name":"Black","start_date":"1984-01-15","end_date":"1998-08-08","salary":"2334.78","city":"Vancouver","description":"Tester","department":"IT","active":"1"},
{"id":"6","first_name":"Linda","last_name":"Green","start_date":"1987-07-30","end_date":"1996-01-04","salary":"4322.78","city":"New York","description":"Tester","department":"QA","active":"1"},
{"id":"7","first_name":"David","last_name":"Larry","start_date":"1990-12-31","end_date":"1998-02-12","salary":"7897.78","city":"New York","description":"Manager","department":"HR","active":"1"}
]


I need to call the function like this:



nest(data,["city","description","department"])


The first parameter is the entire dataset, the second is an array of columns which define the nesting level.



Expected JSON output:



[
{key: "city", value: "Toronto", count: 1, children:
[
{key: "description", value: "Programmer", count: 1, children:
[
{key: "department", value: "Finance", count: 1}
]
}
]
},
{key: "city", value: "Vancouver", count: 2, children:
[
{key: "description", value: "Tester", count: 3, children:
[
{key: "department", value: "Finance", count: 1},
{key: "department", value: "QA", count: 1},
{key: "department", value: "IT", count: 1}
]
},
{key: "description", value: "Manager", count: 1}
]
},

{key: "city", value: "New York", count: 2, children:
[
{key: "description", value: "Tester", count: 1, children:
[
{key: "department", value: "QA", count: 1}
]
},
{key: "description", value: "Manager", count: 1, children:
[
{key: "department", value: "HR", count: 1}
]
}
]
}


]



I've tried writing a few recursive functions but keep getting stuck when I have to dynamically search the tree to avoid duplication.










share|improve this question




















  • 1





    Why {key: "department", value: "Finance", count: 1} instead of {key: "department", value: "Finance", count: 0}? That node has no children.

    – rob mayoff
    Nov 29 '11 at 21:58











  • Welcome to Stack Overflow; please read the faq.

    – zzzzBov
    Nov 29 '11 at 22:01











  • What is count? It is 1 even when children is zero?

    – goat
    Nov 29 '11 at 22:14











  • @esskar - I currently have a recursive function that doesn't work because I would need a sort of xpath syntax to check if an element already exists in the tree

    – WeaponX86
    Nov 30 '11 at 4:12











  • @zzzzBov - Sorry if this question seemed convoluted, I can post the broken code I have

    – WeaponX86
    Nov 30 '11 at 4:23
















12















Original JSON data (flat table):



[
{"id":"1","first_name":"Jason","last_name":"Martin","start_date":"1996-07-25","end_date":"2006-07-25","salary":"1234.56","city":"Toronto","description":"Programmer","department":"Finance","active":"1"},
{"id":"2","first_name":"Alison","last_name":"Mathews","start_date":"1976-03-21","end_date":"1986-02-21","salary":"6661.78","city":"Vancouver","description":"Tester","department":"Finance","active":"1"},
{"id":"3","first_name":"James","last_name":"Smith","start_date":"1978-12-12","end_date":"1990-03-15","salary":"6544.78","city":"Vancouver","description":"Tester","department":"QA","active":"1"},
{"id":"4","first_name":"Celia","last_name":"Rice","start_date":"1982-10-24","end_date":"1999-04-21","salary":"2344.78","city":"Vancouver","description":"Manager","department":"HR","active":"1"},
{"id":"5","first_name":"Robert","last_name":"Black","start_date":"1984-01-15","end_date":"1998-08-08","salary":"2334.78","city":"Vancouver","description":"Tester","department":"IT","active":"1"},
{"id":"6","first_name":"Linda","last_name":"Green","start_date":"1987-07-30","end_date":"1996-01-04","salary":"4322.78","city":"New York","description":"Tester","department":"QA","active":"1"},
{"id":"7","first_name":"David","last_name":"Larry","start_date":"1990-12-31","end_date":"1998-02-12","salary":"7897.78","city":"New York","description":"Manager","department":"HR","active":"1"}
]


I need to call the function like this:



nest(data,["city","description","department"])


The first parameter is the entire dataset, the second is an array of columns which define the nesting level.



Expected JSON output:



[
{key: "city", value: "Toronto", count: 1, children:
[
{key: "description", value: "Programmer", count: 1, children:
[
{key: "department", value: "Finance", count: 1}
]
}
]
},
{key: "city", value: "Vancouver", count: 2, children:
[
{key: "description", value: "Tester", count: 3, children:
[
{key: "department", value: "Finance", count: 1},
{key: "department", value: "QA", count: 1},
{key: "department", value: "IT", count: 1}
]
},
{key: "description", value: "Manager", count: 1}
]
},

{key: "city", value: "New York", count: 2, children:
[
{key: "description", value: "Tester", count: 1, children:
[
{key: "department", value: "QA", count: 1}
]
},
{key: "description", value: "Manager", count: 1, children:
[
{key: "department", value: "HR", count: 1}
]
}
]
}


]



I've tried writing a few recursive functions but keep getting stuck when I have to dynamically search the tree to avoid duplication.










share|improve this question




















  • 1





    Why {key: "department", value: "Finance", count: 1} instead of {key: "department", value: "Finance", count: 0}? That node has no children.

    – rob mayoff
    Nov 29 '11 at 21:58











  • Welcome to Stack Overflow; please read the faq.

    – zzzzBov
    Nov 29 '11 at 22:01











  • What is count? It is 1 even when children is zero?

    – goat
    Nov 29 '11 at 22:14











  • @esskar - I currently have a recursive function that doesn't work because I would need a sort of xpath syntax to check if an element already exists in the tree

    – WeaponX86
    Nov 30 '11 at 4:12











  • @zzzzBov - Sorry if this question seemed convoluted, I can post the broken code I have

    – WeaponX86
    Nov 30 '11 at 4:23














12












12








12


6






Original JSON data (flat table):



[
{"id":"1","first_name":"Jason","last_name":"Martin","start_date":"1996-07-25","end_date":"2006-07-25","salary":"1234.56","city":"Toronto","description":"Programmer","department":"Finance","active":"1"},
{"id":"2","first_name":"Alison","last_name":"Mathews","start_date":"1976-03-21","end_date":"1986-02-21","salary":"6661.78","city":"Vancouver","description":"Tester","department":"Finance","active":"1"},
{"id":"3","first_name":"James","last_name":"Smith","start_date":"1978-12-12","end_date":"1990-03-15","salary":"6544.78","city":"Vancouver","description":"Tester","department":"QA","active":"1"},
{"id":"4","first_name":"Celia","last_name":"Rice","start_date":"1982-10-24","end_date":"1999-04-21","salary":"2344.78","city":"Vancouver","description":"Manager","department":"HR","active":"1"},
{"id":"5","first_name":"Robert","last_name":"Black","start_date":"1984-01-15","end_date":"1998-08-08","salary":"2334.78","city":"Vancouver","description":"Tester","department":"IT","active":"1"},
{"id":"6","first_name":"Linda","last_name":"Green","start_date":"1987-07-30","end_date":"1996-01-04","salary":"4322.78","city":"New York","description":"Tester","department":"QA","active":"1"},
{"id":"7","first_name":"David","last_name":"Larry","start_date":"1990-12-31","end_date":"1998-02-12","salary":"7897.78","city":"New York","description":"Manager","department":"HR","active":"1"}
]


I need to call the function like this:



nest(data,["city","description","department"])


The first parameter is the entire dataset, the second is an array of columns which define the nesting level.



Expected JSON output:



[
{key: "city", value: "Toronto", count: 1, children:
[
{key: "description", value: "Programmer", count: 1, children:
[
{key: "department", value: "Finance", count: 1}
]
}
]
},
{key: "city", value: "Vancouver", count: 2, children:
[
{key: "description", value: "Tester", count: 3, children:
[
{key: "department", value: "Finance", count: 1},
{key: "department", value: "QA", count: 1},
{key: "department", value: "IT", count: 1}
]
},
{key: "description", value: "Manager", count: 1}
]
},

{key: "city", value: "New York", count: 2, children:
[
{key: "description", value: "Tester", count: 1, children:
[
{key: "department", value: "QA", count: 1}
]
},
{key: "description", value: "Manager", count: 1, children:
[
{key: "department", value: "HR", count: 1}
]
}
]
}


]



I've tried writing a few recursive functions but keep getting stuck when I have to dynamically search the tree to avoid duplication.










share|improve this question
















Original JSON data (flat table):



[
{"id":"1","first_name":"Jason","last_name":"Martin","start_date":"1996-07-25","end_date":"2006-07-25","salary":"1234.56","city":"Toronto","description":"Programmer","department":"Finance","active":"1"},
{"id":"2","first_name":"Alison","last_name":"Mathews","start_date":"1976-03-21","end_date":"1986-02-21","salary":"6661.78","city":"Vancouver","description":"Tester","department":"Finance","active":"1"},
{"id":"3","first_name":"James","last_name":"Smith","start_date":"1978-12-12","end_date":"1990-03-15","salary":"6544.78","city":"Vancouver","description":"Tester","department":"QA","active":"1"},
{"id":"4","first_name":"Celia","last_name":"Rice","start_date":"1982-10-24","end_date":"1999-04-21","salary":"2344.78","city":"Vancouver","description":"Manager","department":"HR","active":"1"},
{"id":"5","first_name":"Robert","last_name":"Black","start_date":"1984-01-15","end_date":"1998-08-08","salary":"2334.78","city":"Vancouver","description":"Tester","department":"IT","active":"1"},
{"id":"6","first_name":"Linda","last_name":"Green","start_date":"1987-07-30","end_date":"1996-01-04","salary":"4322.78","city":"New York","description":"Tester","department":"QA","active":"1"},
{"id":"7","first_name":"David","last_name":"Larry","start_date":"1990-12-31","end_date":"1998-02-12","salary":"7897.78","city":"New York","description":"Manager","department":"HR","active":"1"}
]


I need to call the function like this:



nest(data,["city","description","department"])


The first parameter is the entire dataset, the second is an array of columns which define the nesting level.



Expected JSON output:



[
{key: "city", value: "Toronto", count: 1, children:
[
{key: "description", value: "Programmer", count: 1, children:
[
{key: "department", value: "Finance", count: 1}
]
}
]
},
{key: "city", value: "Vancouver", count: 2, children:
[
{key: "description", value: "Tester", count: 3, children:
[
{key: "department", value: "Finance", count: 1},
{key: "department", value: "QA", count: 1},
{key: "department", value: "IT", count: 1}
]
},
{key: "description", value: "Manager", count: 1}
]
},

{key: "city", value: "New York", count: 2, children:
[
{key: "description", value: "Tester", count: 1, children:
[
{key: "department", value: "QA", count: 1}
]
},
{key: "description", value: "Manager", count: 1, children:
[
{key: "department", value: "HR", count: 1}
]
}
]
}


]



I've tried writing a few recursive functions but keep getting stuck when I have to dynamically search the tree to avoid duplication.







javascript






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 29 '11 at 21:59









Jasper

70.7k12132140




70.7k12132140










asked Nov 29 '11 at 21:44









WeaponX86WeaponX86

6517




6517








  • 1





    Why {key: "department", value: "Finance", count: 1} instead of {key: "department", value: "Finance", count: 0}? That node has no children.

    – rob mayoff
    Nov 29 '11 at 21:58











  • Welcome to Stack Overflow; please read the faq.

    – zzzzBov
    Nov 29 '11 at 22:01











  • What is count? It is 1 even when children is zero?

    – goat
    Nov 29 '11 at 22:14











  • @esskar - I currently have a recursive function that doesn't work because I would need a sort of xpath syntax to check if an element already exists in the tree

    – WeaponX86
    Nov 30 '11 at 4:12











  • @zzzzBov - Sorry if this question seemed convoluted, I can post the broken code I have

    – WeaponX86
    Nov 30 '11 at 4:23














  • 1





    Why {key: "department", value: "Finance", count: 1} instead of {key: "department", value: "Finance", count: 0}? That node has no children.

    – rob mayoff
    Nov 29 '11 at 21:58











  • Welcome to Stack Overflow; please read the faq.

    – zzzzBov
    Nov 29 '11 at 22:01











  • What is count? It is 1 even when children is zero?

    – goat
    Nov 29 '11 at 22:14











  • @esskar - I currently have a recursive function that doesn't work because I would need a sort of xpath syntax to check if an element already exists in the tree

    – WeaponX86
    Nov 30 '11 at 4:12











  • @zzzzBov - Sorry if this question seemed convoluted, I can post the broken code I have

    – WeaponX86
    Nov 30 '11 at 4:23








1




1





Why {key: "department", value: "Finance", count: 1} instead of {key: "department", value: "Finance", count: 0}? That node has no children.

– rob mayoff
Nov 29 '11 at 21:58





Why {key: "department", value: "Finance", count: 1} instead of {key: "department", value: "Finance", count: 0}? That node has no children.

– rob mayoff
Nov 29 '11 at 21:58













Welcome to Stack Overflow; please read the faq.

– zzzzBov
Nov 29 '11 at 22:01





Welcome to Stack Overflow; please read the faq.

– zzzzBov
Nov 29 '11 at 22:01













What is count? It is 1 even when children is zero?

– goat
Nov 29 '11 at 22:14





What is count? It is 1 even when children is zero?

– goat
Nov 29 '11 at 22:14













@esskar - I currently have a recursive function that doesn't work because I would need a sort of xpath syntax to check if an element already exists in the tree

– WeaponX86
Nov 30 '11 at 4:12





@esskar - I currently have a recursive function that doesn't work because I would need a sort of xpath syntax to check if an element already exists in the tree

– WeaponX86
Nov 30 '11 at 4:12













@zzzzBov - Sorry if this question seemed convoluted, I can post the broken code I have

– WeaponX86
Nov 30 '11 at 4:23





@zzzzBov - Sorry if this question seemed convoluted, I can post the broken code I have

– WeaponX86
Nov 30 '11 at 4:23












3 Answers
3






active

oldest

votes


















10














Thought this was a fun little question, so I did it... but, I do agree with the people who asked "what have you tried so far". Typically, you should talk about a specific problem.



// Groups a flat array into a tree. 
// "data" is the flat array.
// "keys" is an array of properties to group on.
function groupBy(data, keys) {

if (keys.length == 0) return data;

// The current key to perform the grouping on:
var key = keys[0];

// Loop through the data and construct buckets for
// all of the unique keys:
var groups = {};
for (var i = 0; i < data.length; i++)
{
var row = data[i];
var groupValue = row[key];

if (groups[groupValue] == undefined)
{
groups[groupValue] = new Array();
}

groups[groupValue].push(row);
}

// Remove the first element from the groups array:
keys.reverse();
keys.pop()
keys.reverse();

// If there are no more keys left, we're done:
if (keys.length == 0) return groups;

// Otherwise, handle further groupings:
for (var group in groups)
{
groups[group] = groupBy(groups[group], keys.slice());
}

return groups;
}


Call the method like this:



var groupedData = groupBy(data, ["city","description","department"]);


The output from this method for your data looks like this:



{
"Toronto": {
"Programmer": {
"Finance": [
{
"id": "1", "first_name": "Jason", "last_name": "Martin", "start_date": "1996-07-25", "end_date": "2006-07-25", "salary": "1234.56", "city": "Toronto", "description": "Programmer", "department": "Finance", "active": "1"
}
]
}
},
"Vancouver": {
"Tester": {
"Finance": [
{
"id": "2", "first_name": "Alison", "last_name": "Mathews", "start_date": "1976-03-21", "end_date": "1986-02-21", "salary": "6661.78", "city": "Vancouver", "description": "Tester", "department": "Finance", "active": "1"
}
],
"QA": [
{
"id": "3", "first_name": "James", "last_name": "Smith", "start_date": "1978-12-12", "end_date": "1990-03-15", "salary": "6544.78", "city": "Vancouver", "description": "Tester", "department": "QA", "active": "1"
}
],
"IT": [
{
"id": "5", "first_name": "Robert", "last_name": "Black", "start_date": "1984-01-15", "end_date": "1998-08-08", "salary": "2334.78", "city": "Vancouver", "description": "Tester", "department": "IT", "active": "1"
}
]
},
"Manager": {
"HR": [
{
"id": "4", "first_name": "Celia", "last_name": "Rice", "start_date": "1982-10-24", "end_date": "1999-04-21", "salary": "2344.78", "city": "Vancouver", "description": "Manager", "department": "HR", "active": "1"
}
]
}
},
"New York": {
"Tester": {
"QA": [
{
"id": "6", "first_name": "Linda", "last_name": "Green", "start_date": "1987-07-30", "end_date": "1996-01-04", "salary": "4322.78", "city": "New York", "description": "Tester", "department": "QA", "active": "1"
}
]
},
"Manager": {
"HR": [
{
"id": "7", "first_name": "David", "last_name": "Larry", "start_date": "1990-12-31", "end_date": "1998-02-12", "salary": "7897.78", "city": "New York", "description": "Manager", "department": "HR", "active": "1"
}
]
}
}
}


Because the groups are all javascript objects, you don't need that "count" member. You can simply use the .length property of the array(s).



Loop through the groups using javascript's for (var group in groups) syntax.






share|improve this answer





















  • 1





    That was really helpful, thank you.

    – WeaponX86
    Nov 30 '11 at 4:19











  • A nice solution, saving for later.

    – Oisin Lavery
    Aug 12 '13 at 10:40



















7














You might take a look at the nest() operator from D3.js:
https://github.com/mbostock/d3/blob/48ad44fdeef32b518c6271bb99a9aed376c1a1d6/src/arrays/nest.js
This is part of D3, a larger library, but looking quickly at the code I just linked to, I don't think this has any dependencies, so you should be able to lift the code here for use in your own project. Usage is described here in the docs - you chain .key() methods to define the keys for each layer of the nested structure. In your case, this might look like:



data = d3.nest()
.key(function(d) { return d.city })
.key(function(d) { return d.description })
.entries(data);


The structure this spits out is a little different from what you have, but it's functionally quite similar:



[
{
"key": "Toronto",
"values": [
{
"key": "Programmer",
"values": [
{
"active": "1",
"city": "Toronto",
"department": "Finance",
"description": "Programmer",
"end_date": "2006-07-25",
"first_name": "Jason",
"id": "1",
"last_name": "Martin",
"salary": "1234.56",
"start_date": "1996-07-25"
},
// etc ...
]
}
]
},
// etc ...
]





share|improve this answer


























  • +1 Good one... has a couple benefits over the quick-and-dirty version I put together, including; developer-selectable keys (meaning it would be easy to make the keys case-insensitive or calculated), and sorting. Personally, I'd probably tweak my version to add those features instead of brining in (yet another) library... but nice find!

    – Steve
    Nov 29 '11 at 23:02








  • 1





    Thanks - you don't need the whole library, just the function in the code I linked to, which doesn't have any D3 dependencies. But it's true that it might be overkill for some projects.

    – nrabinowitz
    Nov 29 '11 at 23:45











  • I will definitely take a look at this, nice find!

    – WeaponX86
    Nov 30 '11 at 4:20











  • Awesome this is exactly what I needed. Definitely the cleanest approach possible.

    – parliament
    Nov 28 '17 at 22:43



















0














Building on the example provided by @nrabinowitz, here's the nest function with the originally proposed API of passing the collection and an array of property names as args, using d3.nest under the hood:



function nest(data, keys) {
var nest = d3.nest();
keys.forEach(function(k) {
nest.key(function(d) {
return d[k];
})
});
return nest.entries(data);
}





share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f8318150%2fconvert-flat-array-of-objects-into-nested-array-of-objects%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    10














    Thought this was a fun little question, so I did it... but, I do agree with the people who asked "what have you tried so far". Typically, you should talk about a specific problem.



    // Groups a flat array into a tree. 
    // "data" is the flat array.
    // "keys" is an array of properties to group on.
    function groupBy(data, keys) {

    if (keys.length == 0) return data;

    // The current key to perform the grouping on:
    var key = keys[0];

    // Loop through the data and construct buckets for
    // all of the unique keys:
    var groups = {};
    for (var i = 0; i < data.length; i++)
    {
    var row = data[i];
    var groupValue = row[key];

    if (groups[groupValue] == undefined)
    {
    groups[groupValue] = new Array();
    }

    groups[groupValue].push(row);
    }

    // Remove the first element from the groups array:
    keys.reverse();
    keys.pop()
    keys.reverse();

    // If there are no more keys left, we're done:
    if (keys.length == 0) return groups;

    // Otherwise, handle further groupings:
    for (var group in groups)
    {
    groups[group] = groupBy(groups[group], keys.slice());
    }

    return groups;
    }


    Call the method like this:



    var groupedData = groupBy(data, ["city","description","department"]);


    The output from this method for your data looks like this:



    {
    "Toronto": {
    "Programmer": {
    "Finance": [
    {
    "id": "1", "first_name": "Jason", "last_name": "Martin", "start_date": "1996-07-25", "end_date": "2006-07-25", "salary": "1234.56", "city": "Toronto", "description": "Programmer", "department": "Finance", "active": "1"
    }
    ]
    }
    },
    "Vancouver": {
    "Tester": {
    "Finance": [
    {
    "id": "2", "first_name": "Alison", "last_name": "Mathews", "start_date": "1976-03-21", "end_date": "1986-02-21", "salary": "6661.78", "city": "Vancouver", "description": "Tester", "department": "Finance", "active": "1"
    }
    ],
    "QA": [
    {
    "id": "3", "first_name": "James", "last_name": "Smith", "start_date": "1978-12-12", "end_date": "1990-03-15", "salary": "6544.78", "city": "Vancouver", "description": "Tester", "department": "QA", "active": "1"
    }
    ],
    "IT": [
    {
    "id": "5", "first_name": "Robert", "last_name": "Black", "start_date": "1984-01-15", "end_date": "1998-08-08", "salary": "2334.78", "city": "Vancouver", "description": "Tester", "department": "IT", "active": "1"
    }
    ]
    },
    "Manager": {
    "HR": [
    {
    "id": "4", "first_name": "Celia", "last_name": "Rice", "start_date": "1982-10-24", "end_date": "1999-04-21", "salary": "2344.78", "city": "Vancouver", "description": "Manager", "department": "HR", "active": "1"
    }
    ]
    }
    },
    "New York": {
    "Tester": {
    "QA": [
    {
    "id": "6", "first_name": "Linda", "last_name": "Green", "start_date": "1987-07-30", "end_date": "1996-01-04", "salary": "4322.78", "city": "New York", "description": "Tester", "department": "QA", "active": "1"
    }
    ]
    },
    "Manager": {
    "HR": [
    {
    "id": "7", "first_name": "David", "last_name": "Larry", "start_date": "1990-12-31", "end_date": "1998-02-12", "salary": "7897.78", "city": "New York", "description": "Manager", "department": "HR", "active": "1"
    }
    ]
    }
    }
    }


    Because the groups are all javascript objects, you don't need that "count" member. You can simply use the .length property of the array(s).



    Loop through the groups using javascript's for (var group in groups) syntax.






    share|improve this answer





















    • 1





      That was really helpful, thank you.

      – WeaponX86
      Nov 30 '11 at 4:19











    • A nice solution, saving for later.

      – Oisin Lavery
      Aug 12 '13 at 10:40
















    10














    Thought this was a fun little question, so I did it... but, I do agree with the people who asked "what have you tried so far". Typically, you should talk about a specific problem.



    // Groups a flat array into a tree. 
    // "data" is the flat array.
    // "keys" is an array of properties to group on.
    function groupBy(data, keys) {

    if (keys.length == 0) return data;

    // The current key to perform the grouping on:
    var key = keys[0];

    // Loop through the data and construct buckets for
    // all of the unique keys:
    var groups = {};
    for (var i = 0; i < data.length; i++)
    {
    var row = data[i];
    var groupValue = row[key];

    if (groups[groupValue] == undefined)
    {
    groups[groupValue] = new Array();
    }

    groups[groupValue].push(row);
    }

    // Remove the first element from the groups array:
    keys.reverse();
    keys.pop()
    keys.reverse();

    // If there are no more keys left, we're done:
    if (keys.length == 0) return groups;

    // Otherwise, handle further groupings:
    for (var group in groups)
    {
    groups[group] = groupBy(groups[group], keys.slice());
    }

    return groups;
    }


    Call the method like this:



    var groupedData = groupBy(data, ["city","description","department"]);


    The output from this method for your data looks like this:



    {
    "Toronto": {
    "Programmer": {
    "Finance": [
    {
    "id": "1", "first_name": "Jason", "last_name": "Martin", "start_date": "1996-07-25", "end_date": "2006-07-25", "salary": "1234.56", "city": "Toronto", "description": "Programmer", "department": "Finance", "active": "1"
    }
    ]
    }
    },
    "Vancouver": {
    "Tester": {
    "Finance": [
    {
    "id": "2", "first_name": "Alison", "last_name": "Mathews", "start_date": "1976-03-21", "end_date": "1986-02-21", "salary": "6661.78", "city": "Vancouver", "description": "Tester", "department": "Finance", "active": "1"
    }
    ],
    "QA": [
    {
    "id": "3", "first_name": "James", "last_name": "Smith", "start_date": "1978-12-12", "end_date": "1990-03-15", "salary": "6544.78", "city": "Vancouver", "description": "Tester", "department": "QA", "active": "1"
    }
    ],
    "IT": [
    {
    "id": "5", "first_name": "Robert", "last_name": "Black", "start_date": "1984-01-15", "end_date": "1998-08-08", "salary": "2334.78", "city": "Vancouver", "description": "Tester", "department": "IT", "active": "1"
    }
    ]
    },
    "Manager": {
    "HR": [
    {
    "id": "4", "first_name": "Celia", "last_name": "Rice", "start_date": "1982-10-24", "end_date": "1999-04-21", "salary": "2344.78", "city": "Vancouver", "description": "Manager", "department": "HR", "active": "1"
    }
    ]
    }
    },
    "New York": {
    "Tester": {
    "QA": [
    {
    "id": "6", "first_name": "Linda", "last_name": "Green", "start_date": "1987-07-30", "end_date": "1996-01-04", "salary": "4322.78", "city": "New York", "description": "Tester", "department": "QA", "active": "1"
    }
    ]
    },
    "Manager": {
    "HR": [
    {
    "id": "7", "first_name": "David", "last_name": "Larry", "start_date": "1990-12-31", "end_date": "1998-02-12", "salary": "7897.78", "city": "New York", "description": "Manager", "department": "HR", "active": "1"
    }
    ]
    }
    }
    }


    Because the groups are all javascript objects, you don't need that "count" member. You can simply use the .length property of the array(s).



    Loop through the groups using javascript's for (var group in groups) syntax.






    share|improve this answer





















    • 1





      That was really helpful, thank you.

      – WeaponX86
      Nov 30 '11 at 4:19











    • A nice solution, saving for later.

      – Oisin Lavery
      Aug 12 '13 at 10:40














    10












    10








    10







    Thought this was a fun little question, so I did it... but, I do agree with the people who asked "what have you tried so far". Typically, you should talk about a specific problem.



    // Groups a flat array into a tree. 
    // "data" is the flat array.
    // "keys" is an array of properties to group on.
    function groupBy(data, keys) {

    if (keys.length == 0) return data;

    // The current key to perform the grouping on:
    var key = keys[0];

    // Loop through the data and construct buckets for
    // all of the unique keys:
    var groups = {};
    for (var i = 0; i < data.length; i++)
    {
    var row = data[i];
    var groupValue = row[key];

    if (groups[groupValue] == undefined)
    {
    groups[groupValue] = new Array();
    }

    groups[groupValue].push(row);
    }

    // Remove the first element from the groups array:
    keys.reverse();
    keys.pop()
    keys.reverse();

    // If there are no more keys left, we're done:
    if (keys.length == 0) return groups;

    // Otherwise, handle further groupings:
    for (var group in groups)
    {
    groups[group] = groupBy(groups[group], keys.slice());
    }

    return groups;
    }


    Call the method like this:



    var groupedData = groupBy(data, ["city","description","department"]);


    The output from this method for your data looks like this:



    {
    "Toronto": {
    "Programmer": {
    "Finance": [
    {
    "id": "1", "first_name": "Jason", "last_name": "Martin", "start_date": "1996-07-25", "end_date": "2006-07-25", "salary": "1234.56", "city": "Toronto", "description": "Programmer", "department": "Finance", "active": "1"
    }
    ]
    }
    },
    "Vancouver": {
    "Tester": {
    "Finance": [
    {
    "id": "2", "first_name": "Alison", "last_name": "Mathews", "start_date": "1976-03-21", "end_date": "1986-02-21", "salary": "6661.78", "city": "Vancouver", "description": "Tester", "department": "Finance", "active": "1"
    }
    ],
    "QA": [
    {
    "id": "3", "first_name": "James", "last_name": "Smith", "start_date": "1978-12-12", "end_date": "1990-03-15", "salary": "6544.78", "city": "Vancouver", "description": "Tester", "department": "QA", "active": "1"
    }
    ],
    "IT": [
    {
    "id": "5", "first_name": "Robert", "last_name": "Black", "start_date": "1984-01-15", "end_date": "1998-08-08", "salary": "2334.78", "city": "Vancouver", "description": "Tester", "department": "IT", "active": "1"
    }
    ]
    },
    "Manager": {
    "HR": [
    {
    "id": "4", "first_name": "Celia", "last_name": "Rice", "start_date": "1982-10-24", "end_date": "1999-04-21", "salary": "2344.78", "city": "Vancouver", "description": "Manager", "department": "HR", "active": "1"
    }
    ]
    }
    },
    "New York": {
    "Tester": {
    "QA": [
    {
    "id": "6", "first_name": "Linda", "last_name": "Green", "start_date": "1987-07-30", "end_date": "1996-01-04", "salary": "4322.78", "city": "New York", "description": "Tester", "department": "QA", "active": "1"
    }
    ]
    },
    "Manager": {
    "HR": [
    {
    "id": "7", "first_name": "David", "last_name": "Larry", "start_date": "1990-12-31", "end_date": "1998-02-12", "salary": "7897.78", "city": "New York", "description": "Manager", "department": "HR", "active": "1"
    }
    ]
    }
    }
    }


    Because the groups are all javascript objects, you don't need that "count" member. You can simply use the .length property of the array(s).



    Loop through the groups using javascript's for (var group in groups) syntax.






    share|improve this answer















    Thought this was a fun little question, so I did it... but, I do agree with the people who asked "what have you tried so far". Typically, you should talk about a specific problem.



    // Groups a flat array into a tree. 
    // "data" is the flat array.
    // "keys" is an array of properties to group on.
    function groupBy(data, keys) {

    if (keys.length == 0) return data;

    // The current key to perform the grouping on:
    var key = keys[0];

    // Loop through the data and construct buckets for
    // all of the unique keys:
    var groups = {};
    for (var i = 0; i < data.length; i++)
    {
    var row = data[i];
    var groupValue = row[key];

    if (groups[groupValue] == undefined)
    {
    groups[groupValue] = new Array();
    }

    groups[groupValue].push(row);
    }

    // Remove the first element from the groups array:
    keys.reverse();
    keys.pop()
    keys.reverse();

    // If there are no more keys left, we're done:
    if (keys.length == 0) return groups;

    // Otherwise, handle further groupings:
    for (var group in groups)
    {
    groups[group] = groupBy(groups[group], keys.slice());
    }

    return groups;
    }


    Call the method like this:



    var groupedData = groupBy(data, ["city","description","department"]);


    The output from this method for your data looks like this:



    {
    "Toronto": {
    "Programmer": {
    "Finance": [
    {
    "id": "1", "first_name": "Jason", "last_name": "Martin", "start_date": "1996-07-25", "end_date": "2006-07-25", "salary": "1234.56", "city": "Toronto", "description": "Programmer", "department": "Finance", "active": "1"
    }
    ]
    }
    },
    "Vancouver": {
    "Tester": {
    "Finance": [
    {
    "id": "2", "first_name": "Alison", "last_name": "Mathews", "start_date": "1976-03-21", "end_date": "1986-02-21", "salary": "6661.78", "city": "Vancouver", "description": "Tester", "department": "Finance", "active": "1"
    }
    ],
    "QA": [
    {
    "id": "3", "first_name": "James", "last_name": "Smith", "start_date": "1978-12-12", "end_date": "1990-03-15", "salary": "6544.78", "city": "Vancouver", "description": "Tester", "department": "QA", "active": "1"
    }
    ],
    "IT": [
    {
    "id": "5", "first_name": "Robert", "last_name": "Black", "start_date": "1984-01-15", "end_date": "1998-08-08", "salary": "2334.78", "city": "Vancouver", "description": "Tester", "department": "IT", "active": "1"
    }
    ]
    },
    "Manager": {
    "HR": [
    {
    "id": "4", "first_name": "Celia", "last_name": "Rice", "start_date": "1982-10-24", "end_date": "1999-04-21", "salary": "2344.78", "city": "Vancouver", "description": "Manager", "department": "HR", "active": "1"
    }
    ]
    }
    },
    "New York": {
    "Tester": {
    "QA": [
    {
    "id": "6", "first_name": "Linda", "last_name": "Green", "start_date": "1987-07-30", "end_date": "1996-01-04", "salary": "4322.78", "city": "New York", "description": "Tester", "department": "QA", "active": "1"
    }
    ]
    },
    "Manager": {
    "HR": [
    {
    "id": "7", "first_name": "David", "last_name": "Larry", "start_date": "1990-12-31", "end_date": "1998-02-12", "salary": "7897.78", "city": "New York", "description": "Manager", "department": "HR", "active": "1"
    }
    ]
    }
    }
    }


    Because the groups are all javascript objects, you don't need that "count" member. You can simply use the .length property of the array(s).



    Loop through the groups using javascript's for (var group in groups) syntax.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 29 '11 at 22:51

























    answered Nov 29 '11 at 22:13









    SteveSteve

    24.9k1389116




    24.9k1389116








    • 1





      That was really helpful, thank you.

      – WeaponX86
      Nov 30 '11 at 4:19











    • A nice solution, saving for later.

      – Oisin Lavery
      Aug 12 '13 at 10:40














    • 1





      That was really helpful, thank you.

      – WeaponX86
      Nov 30 '11 at 4:19











    • A nice solution, saving for later.

      – Oisin Lavery
      Aug 12 '13 at 10:40








    1




    1





    That was really helpful, thank you.

    – WeaponX86
    Nov 30 '11 at 4:19





    That was really helpful, thank you.

    – WeaponX86
    Nov 30 '11 at 4:19













    A nice solution, saving for later.

    – Oisin Lavery
    Aug 12 '13 at 10:40





    A nice solution, saving for later.

    – Oisin Lavery
    Aug 12 '13 at 10:40













    7














    You might take a look at the nest() operator from D3.js:
    https://github.com/mbostock/d3/blob/48ad44fdeef32b518c6271bb99a9aed376c1a1d6/src/arrays/nest.js
    This is part of D3, a larger library, but looking quickly at the code I just linked to, I don't think this has any dependencies, so you should be able to lift the code here for use in your own project. Usage is described here in the docs - you chain .key() methods to define the keys for each layer of the nested structure. In your case, this might look like:



    data = d3.nest()
    .key(function(d) { return d.city })
    .key(function(d) { return d.description })
    .entries(data);


    The structure this spits out is a little different from what you have, but it's functionally quite similar:



    [
    {
    "key": "Toronto",
    "values": [
    {
    "key": "Programmer",
    "values": [
    {
    "active": "1",
    "city": "Toronto",
    "department": "Finance",
    "description": "Programmer",
    "end_date": "2006-07-25",
    "first_name": "Jason",
    "id": "1",
    "last_name": "Martin",
    "salary": "1234.56",
    "start_date": "1996-07-25"
    },
    // etc ...
    ]
    }
    ]
    },
    // etc ...
    ]





    share|improve this answer


























    • +1 Good one... has a couple benefits over the quick-and-dirty version I put together, including; developer-selectable keys (meaning it would be easy to make the keys case-insensitive or calculated), and sorting. Personally, I'd probably tweak my version to add those features instead of brining in (yet another) library... but nice find!

      – Steve
      Nov 29 '11 at 23:02








    • 1





      Thanks - you don't need the whole library, just the function in the code I linked to, which doesn't have any D3 dependencies. But it's true that it might be overkill for some projects.

      – nrabinowitz
      Nov 29 '11 at 23:45











    • I will definitely take a look at this, nice find!

      – WeaponX86
      Nov 30 '11 at 4:20











    • Awesome this is exactly what I needed. Definitely the cleanest approach possible.

      – parliament
      Nov 28 '17 at 22:43
















    7














    You might take a look at the nest() operator from D3.js:
    https://github.com/mbostock/d3/blob/48ad44fdeef32b518c6271bb99a9aed376c1a1d6/src/arrays/nest.js
    This is part of D3, a larger library, but looking quickly at the code I just linked to, I don't think this has any dependencies, so you should be able to lift the code here for use in your own project. Usage is described here in the docs - you chain .key() methods to define the keys for each layer of the nested structure. In your case, this might look like:



    data = d3.nest()
    .key(function(d) { return d.city })
    .key(function(d) { return d.description })
    .entries(data);


    The structure this spits out is a little different from what you have, but it's functionally quite similar:



    [
    {
    "key": "Toronto",
    "values": [
    {
    "key": "Programmer",
    "values": [
    {
    "active": "1",
    "city": "Toronto",
    "department": "Finance",
    "description": "Programmer",
    "end_date": "2006-07-25",
    "first_name": "Jason",
    "id": "1",
    "last_name": "Martin",
    "salary": "1234.56",
    "start_date": "1996-07-25"
    },
    // etc ...
    ]
    }
    ]
    },
    // etc ...
    ]





    share|improve this answer


























    • +1 Good one... has a couple benefits over the quick-and-dirty version I put together, including; developer-selectable keys (meaning it would be easy to make the keys case-insensitive or calculated), and sorting. Personally, I'd probably tweak my version to add those features instead of brining in (yet another) library... but nice find!

      – Steve
      Nov 29 '11 at 23:02








    • 1





      Thanks - you don't need the whole library, just the function in the code I linked to, which doesn't have any D3 dependencies. But it's true that it might be overkill for some projects.

      – nrabinowitz
      Nov 29 '11 at 23:45











    • I will definitely take a look at this, nice find!

      – WeaponX86
      Nov 30 '11 at 4:20











    • Awesome this is exactly what I needed. Definitely the cleanest approach possible.

      – parliament
      Nov 28 '17 at 22:43














    7












    7








    7







    You might take a look at the nest() operator from D3.js:
    https://github.com/mbostock/d3/blob/48ad44fdeef32b518c6271bb99a9aed376c1a1d6/src/arrays/nest.js
    This is part of D3, a larger library, but looking quickly at the code I just linked to, I don't think this has any dependencies, so you should be able to lift the code here for use in your own project. Usage is described here in the docs - you chain .key() methods to define the keys for each layer of the nested structure. In your case, this might look like:



    data = d3.nest()
    .key(function(d) { return d.city })
    .key(function(d) { return d.description })
    .entries(data);


    The structure this spits out is a little different from what you have, but it's functionally quite similar:



    [
    {
    "key": "Toronto",
    "values": [
    {
    "key": "Programmer",
    "values": [
    {
    "active": "1",
    "city": "Toronto",
    "department": "Finance",
    "description": "Programmer",
    "end_date": "2006-07-25",
    "first_name": "Jason",
    "id": "1",
    "last_name": "Martin",
    "salary": "1234.56",
    "start_date": "1996-07-25"
    },
    // etc ...
    ]
    }
    ]
    },
    // etc ...
    ]





    share|improve this answer















    You might take a look at the nest() operator from D3.js:
    https://github.com/mbostock/d3/blob/48ad44fdeef32b518c6271bb99a9aed376c1a1d6/src/arrays/nest.js
    This is part of D3, a larger library, but looking quickly at the code I just linked to, I don't think this has any dependencies, so you should be able to lift the code here for use in your own project. Usage is described here in the docs - you chain .key() methods to define the keys for each layer of the nested structure. In your case, this might look like:



    data = d3.nest()
    .key(function(d) { return d.city })
    .key(function(d) { return d.description })
    .entries(data);


    The structure this spits out is a little different from what you have, but it's functionally quite similar:



    [
    {
    "key": "Toronto",
    "values": [
    {
    "key": "Programmer",
    "values": [
    {
    "active": "1",
    "city": "Toronto",
    "department": "Finance",
    "description": "Programmer",
    "end_date": "2006-07-25",
    "first_name": "Jason",
    "id": "1",
    "last_name": "Martin",
    "salary": "1234.56",
    "start_date": "1996-07-25"
    },
    // etc ...
    ]
    }
    ]
    },
    // etc ...
    ]






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 20 '14 at 20:57









    user2357169

    6719




    6719










    answered Nov 29 '11 at 22:55









    nrabinowitznrabinowitz

    48.1k8131151




    48.1k8131151













    • +1 Good one... has a couple benefits over the quick-and-dirty version I put together, including; developer-selectable keys (meaning it would be easy to make the keys case-insensitive or calculated), and sorting. Personally, I'd probably tweak my version to add those features instead of brining in (yet another) library... but nice find!

      – Steve
      Nov 29 '11 at 23:02








    • 1





      Thanks - you don't need the whole library, just the function in the code I linked to, which doesn't have any D3 dependencies. But it's true that it might be overkill for some projects.

      – nrabinowitz
      Nov 29 '11 at 23:45











    • I will definitely take a look at this, nice find!

      – WeaponX86
      Nov 30 '11 at 4:20











    • Awesome this is exactly what I needed. Definitely the cleanest approach possible.

      – parliament
      Nov 28 '17 at 22:43



















    • +1 Good one... has a couple benefits over the quick-and-dirty version I put together, including; developer-selectable keys (meaning it would be easy to make the keys case-insensitive or calculated), and sorting. Personally, I'd probably tweak my version to add those features instead of brining in (yet another) library... but nice find!

      – Steve
      Nov 29 '11 at 23:02








    • 1





      Thanks - you don't need the whole library, just the function in the code I linked to, which doesn't have any D3 dependencies. But it's true that it might be overkill for some projects.

      – nrabinowitz
      Nov 29 '11 at 23:45











    • I will definitely take a look at this, nice find!

      – WeaponX86
      Nov 30 '11 at 4:20











    • Awesome this is exactly what I needed. Definitely the cleanest approach possible.

      – parliament
      Nov 28 '17 at 22:43

















    +1 Good one... has a couple benefits over the quick-and-dirty version I put together, including; developer-selectable keys (meaning it would be easy to make the keys case-insensitive or calculated), and sorting. Personally, I'd probably tweak my version to add those features instead of brining in (yet another) library... but nice find!

    – Steve
    Nov 29 '11 at 23:02







    +1 Good one... has a couple benefits over the quick-and-dirty version I put together, including; developer-selectable keys (meaning it would be easy to make the keys case-insensitive or calculated), and sorting. Personally, I'd probably tweak my version to add those features instead of brining in (yet another) library... but nice find!

    – Steve
    Nov 29 '11 at 23:02






    1




    1





    Thanks - you don't need the whole library, just the function in the code I linked to, which doesn't have any D3 dependencies. But it's true that it might be overkill for some projects.

    – nrabinowitz
    Nov 29 '11 at 23:45





    Thanks - you don't need the whole library, just the function in the code I linked to, which doesn't have any D3 dependencies. But it's true that it might be overkill for some projects.

    – nrabinowitz
    Nov 29 '11 at 23:45













    I will definitely take a look at this, nice find!

    – WeaponX86
    Nov 30 '11 at 4:20





    I will definitely take a look at this, nice find!

    – WeaponX86
    Nov 30 '11 at 4:20













    Awesome this is exactly what I needed. Definitely the cleanest approach possible.

    – parliament
    Nov 28 '17 at 22:43





    Awesome this is exactly what I needed. Definitely the cleanest approach possible.

    – parliament
    Nov 28 '17 at 22:43











    0














    Building on the example provided by @nrabinowitz, here's the nest function with the originally proposed API of passing the collection and an array of property names as args, using d3.nest under the hood:



    function nest(data, keys) {
    var nest = d3.nest();
    keys.forEach(function(k) {
    nest.key(function(d) {
    return d[k];
    })
    });
    return nest.entries(data);
    }





    share|improve this answer






























      0














      Building on the example provided by @nrabinowitz, here's the nest function with the originally proposed API of passing the collection and an array of property names as args, using d3.nest under the hood:



      function nest(data, keys) {
      var nest = d3.nest();
      keys.forEach(function(k) {
      nest.key(function(d) {
      return d[k];
      })
      });
      return nest.entries(data);
      }





      share|improve this answer




























        0












        0








        0







        Building on the example provided by @nrabinowitz, here's the nest function with the originally proposed API of passing the collection and an array of property names as args, using d3.nest under the hood:



        function nest(data, keys) {
        var nest = d3.nest();
        keys.forEach(function(k) {
        nest.key(function(d) {
        return d[k];
        })
        });
        return nest.entries(data);
        }





        share|improve this answer















        Building on the example provided by @nrabinowitz, here's the nest function with the originally proposed API of passing the collection and an array of property names as args, using d3.nest under the hood:



        function nest(data, keys) {
        var nest = d3.nest();
        keys.forEach(function(k) {
        nest.key(function(d) {
        return d[k];
        })
        });
        return nest.entries(data);
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 8 '16 at 20:38

























        answered Dec 8 '16 at 16:13









        EricEric

        727612




        727612






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f8318150%2fconvert-flat-array-of-objects-into-nested-array-of-objects%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

            Alcedinidae

            Origin of the phrase “under your belt”?