Sort array by child's child












0














The situation is: I have an array of objects, in which every object has an array of objects. The array looks like this:



[
{
"dislikes": [
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511001,
"timezoneOffset": -60,
"year": 118
},
},
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511008,
"timezoneOffset": -60,
"year": 118
},
}
],
},
{
"dislikes": [
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511011,
"timezoneOffset": -60,
"year": 118
},
},
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511028,
"timezoneOffset": -60,
"year": 118
},
}
],
}
]


So I want to sort the users, and the dislikes by the time in their dislikes. So the user with the earliest dislike would be first, as well as the earliest dislike would be first in each users' dislikes array. I believe I have to do multiple sorts, but how can I do that exactly?










share|improve this question






















  • Can you please clarify why you need to break the createDate into elements if the requirement is to sort it?
    – Carlos Martins
    Nov 23 '18 at 9:59










  • What do you mean? I want to sort the array of users and dislikes by the time in createdDate. The createdDate object is created with Java and I have no control over it. I just have to sort it.
    – Alex Ironside
    Nov 23 '18 at 10:01
















0














The situation is: I have an array of objects, in which every object has an array of objects. The array looks like this:



[
{
"dislikes": [
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511001,
"timezoneOffset": -60,
"year": 118
},
},
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511008,
"timezoneOffset": -60,
"year": 118
},
}
],
},
{
"dislikes": [
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511011,
"timezoneOffset": -60,
"year": 118
},
},
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511028,
"timezoneOffset": -60,
"year": 118
},
}
],
}
]


So I want to sort the users, and the dislikes by the time in their dislikes. So the user with the earliest dislike would be first, as well as the earliest dislike would be first in each users' dislikes array. I believe I have to do multiple sorts, but how can I do that exactly?










share|improve this question






















  • Can you please clarify why you need to break the createDate into elements if the requirement is to sort it?
    – Carlos Martins
    Nov 23 '18 at 9:59










  • What do you mean? I want to sort the array of users and dislikes by the time in createdDate. The createdDate object is created with Java and I have no control over it. I just have to sort it.
    – Alex Ironside
    Nov 23 '18 at 10:01














0












0








0







The situation is: I have an array of objects, in which every object has an array of objects. The array looks like this:



[
{
"dislikes": [
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511001,
"timezoneOffset": -60,
"year": 118
},
},
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511008,
"timezoneOffset": -60,
"year": 118
},
}
],
},
{
"dislikes": [
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511011,
"timezoneOffset": -60,
"year": 118
},
},
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511028,
"timezoneOffset": -60,
"year": 118
},
}
],
}
]


So I want to sort the users, and the dislikes by the time in their dislikes. So the user with the earliest dislike would be first, as well as the earliest dislike would be first in each users' dislikes array. I believe I have to do multiple sorts, but how can I do that exactly?










share|improve this question













The situation is: I have an array of objects, in which every object has an array of objects. The array looks like this:



[
{
"dislikes": [
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511001,
"timezoneOffset": -60,
"year": 118
},
},
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511008,
"timezoneOffset": -60,
"year": 118
},
}
],
},
{
"dislikes": [
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511011,
"timezoneOffset": -60,
"year": 118
},
},
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511028,
"timezoneOffset": -60,
"year": 118
},
}
],
}
]


So I want to sort the users, and the dislikes by the time in their dislikes. So the user with the earliest dislike would be first, as well as the earliest dislike would be first in each users' dislikes array. I believe I have to do multiple sorts, but how can I do that exactly?







javascript arrays sorting






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 23 '18 at 9:49









Alex Ironside

1,004723




1,004723












  • Can you please clarify why you need to break the createDate into elements if the requirement is to sort it?
    – Carlos Martins
    Nov 23 '18 at 9:59










  • What do you mean? I want to sort the array of users and dislikes by the time in createdDate. The createdDate object is created with Java and I have no control over it. I just have to sort it.
    – Alex Ironside
    Nov 23 '18 at 10:01


















  • Can you please clarify why you need to break the createDate into elements if the requirement is to sort it?
    – Carlos Martins
    Nov 23 '18 at 9:59










  • What do you mean? I want to sort the array of users and dislikes by the time in createdDate. The createdDate object is created with Java and I have no control over it. I just have to sort it.
    – Alex Ironside
    Nov 23 '18 at 10:01
















Can you please clarify why you need to break the createDate into elements if the requirement is to sort it?
– Carlos Martins
Nov 23 '18 at 9:59




Can you please clarify why you need to break the createDate into elements if the requirement is to sort it?
– Carlos Martins
Nov 23 '18 at 9:59












What do you mean? I want to sort the array of users and dislikes by the time in createdDate. The createdDate object is created with Java and I have no control over it. I just have to sort it.
– Alex Ironside
Nov 23 '18 at 10:01




What do you mean? I want to sort the array of users and dislikes by the time in createdDate. The createdDate object is created with Java and I have no control over it. I just have to sort it.
– Alex Ironside
Nov 23 '18 at 10:01












4 Answers
4






active

oldest

votes


















1














Check the code below. This will let you sort based on time:



function sortByTime(obj1, obj2){
return obj1.time - obj2.time;
}

array.sort((obj1, obj2)=>{
obj1.dislikes.sort(sortByTime);
obj2.dislikes.sort(sortByTime);
return obj1.dislikes[0].time - obj2.dislikes[0].time;
});


I did not get what you meant by earliest time. The above code sorts time in ascending order.



NOTE: The above code does not handle edge cases where a property night be missing






share|improve this answer























  • Mutates elements in array and is very inefficient to sort on every compare. Will also crash or bug out when user has no dislikes.
    – HMR
    Nov 23 '18 at 10:20





















2














You can map the items and add a property to it containing the earliest dislike and then sort on that:






const data = [{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511001,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511008,"timezoneOffset":-60,"year":118}}]},{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511011,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511028,"timezoneOffset":-60,"year":118}}]}];

console.log(
data
//map and add newestDislike property
.map((d) => ({
...d,
//reduce and only takes the lowest time value
newestDislike: (d.dislikes || ).reduce(
(result, item) =>
item.createDate.time < result
? item.createDate.time
: result,
Infinity, //defaults to infinity (if no dislikes)
),
}))
.sort((a, b) => a.newestDislike - b.newestDislike),
);





If the dislikes in the user are already sorted by oldest date first then you can skip the map and reduce part. If a user can have empty dislikes or undefined then make sure you use a getter function with a default so your code won't crash:



//gets a nested prop from object or returns defaultValue
const get = (o = {}, path, defaultValue) => {
const recur = (o, path, defaultValue) => {
if (o === undefined) return defaultValue;
if (path.length === 0) return o;
if (!(path[0] in o)) return defaultValue;
return recur(o[path[0]], path.slice(1), defaultValue);
};
return recur(o, path, defaultValue);
};
console.log(
data.sort(
(a, b) =>
get(
a,
['dislikes', 0, 'createDate', 'time'],
Infinity,
) -
get(
b,
['dislikes', 0, 'createDate', 'time'],
Infinity,
),
),
);





share|improve this answer



















  • 1




    Good answer that handles undefined and other checks
    – Kruthika C S
    Nov 23 '18 at 11:40



















2














//Supply the array you've metioned as the argument users to the below method, sortDislikesForAllUsers 
let sortDislikesForAllUsers = function(users) {
return users.map(user => {
return {
dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
}
})
}
//Supply the array returned in the above method as input to the below method, sortUsers
let sortUsers = function(arrayOfSortedDislikesPerUser) {
return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
}

let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
console.log(finalSortedArray);



In the below snippet,
sortDislikesForAllUsers This method sorts the dislikes for individual
users



sortUsers This method sorts the users based on the first dislike time
of the sorted dislikes array obtained from the above method




Simple :)




Run the below snippet. You can directly copy paste it in your code!







    let users = [{
"dislikes": [
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511001,
"timezoneOffset": -60,
"year": 118
},
},
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511008,
"timezoneOffset": -60,
"year": 118
},
}
],
},
{
"dislikes": [
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511011,
"timezoneOffset": -60,
"year": 118
},
},
{
"createDate": {
"date": 11,
"day": 0,
"hours": 18,
"minutes": 15,
"month": 10,
"seconds": 11,
"time": 1541956511028,
"timezoneOffset": -60,
"year": 118
},
}
],
}]

let sortDislikesForAllUsers = function(users) {
return users.map(user => {
return {
dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
}
})
}

let sortUsers = function(arrayOfSortedDislikesPerUser) {
return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
}

let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
console.log(finalSortedArray);





EDIT: WRT to the comment by @HMR:
1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array.
let noRefCopy = new Array()
noRefCopy = noRefCopy.concat(originalArr)

Now, perform sorting on the copy and return the same.



2. If you wanna have checks for undefined etc, sure you can.




The above answer attempts to address the logic. Sure we can address the above 2 concerns if the question is really specific to them.




Cheers,

Kruthika






share|improve this answer























  • Sort mutates the array so after executing sortDislikesForAllUsers you've changed the original array (usually not a good thing). What if a user has no dislikes, say dislikes is an empty array or even undefined for a user?
    – HMR
    Nov 23 '18 at 11:06










  • Thanks for the comment HMR. The points you mentioned can be effectively addressed. 1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array. let noRefCopy = new Array() noRefCopy = noRefCopy.concat(originalArr) Now, perform sorting on the copy and return the same. 2. If you wanna have checkes for undefined etc, sure you can. The above answer attempts to address the logic. Sure we can address the above 2 concerns. PS:If you say, creating copy is a space concern now, you must create copy if you wanna avoid mutation
    – Kruthika C S
    Nov 23 '18 at 11:29












  • user.dislikes.slice().sort(... would fix the mutation as well but a user without dislikes (empty array or undefined) would crash your code. To fix that you will need a getter (see second part of my answer)
    – HMR
    Nov 23 '18 at 11:35





















1














Something like as follows (with lodash.js)



_.each(users, (u) => { u.dislikes = _.sortBy(u.dislikes, 'createdDate.time'); });
users = _.sortBy(users, 'dislikes[0].createdDate.time');





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%2f53444228%2fsort-array-by-childs-child%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Check the code below. This will let you sort based on time:



    function sortByTime(obj1, obj2){
    return obj1.time - obj2.time;
    }

    array.sort((obj1, obj2)=>{
    obj1.dislikes.sort(sortByTime);
    obj2.dislikes.sort(sortByTime);
    return obj1.dislikes[0].time - obj2.dislikes[0].time;
    });


    I did not get what you meant by earliest time. The above code sorts time in ascending order.



    NOTE: The above code does not handle edge cases where a property night be missing






    share|improve this answer























    • Mutates elements in array and is very inefficient to sort on every compare. Will also crash or bug out when user has no dislikes.
      – HMR
      Nov 23 '18 at 10:20


















    1














    Check the code below. This will let you sort based on time:



    function sortByTime(obj1, obj2){
    return obj1.time - obj2.time;
    }

    array.sort((obj1, obj2)=>{
    obj1.dislikes.sort(sortByTime);
    obj2.dislikes.sort(sortByTime);
    return obj1.dislikes[0].time - obj2.dislikes[0].time;
    });


    I did not get what you meant by earliest time. The above code sorts time in ascending order.



    NOTE: The above code does not handle edge cases where a property night be missing






    share|improve this answer























    • Mutates elements in array and is very inefficient to sort on every compare. Will also crash or bug out when user has no dislikes.
      – HMR
      Nov 23 '18 at 10:20
















    1












    1








    1






    Check the code below. This will let you sort based on time:



    function sortByTime(obj1, obj2){
    return obj1.time - obj2.time;
    }

    array.sort((obj1, obj2)=>{
    obj1.dislikes.sort(sortByTime);
    obj2.dislikes.sort(sortByTime);
    return obj1.dislikes[0].time - obj2.dislikes[0].time;
    });


    I did not get what you meant by earliest time. The above code sorts time in ascending order.



    NOTE: The above code does not handle edge cases where a property night be missing






    share|improve this answer














    Check the code below. This will let you sort based on time:



    function sortByTime(obj1, obj2){
    return obj1.time - obj2.time;
    }

    array.sort((obj1, obj2)=>{
    obj1.dislikes.sort(sortByTime);
    obj2.dislikes.sort(sortByTime);
    return obj1.dislikes[0].time - obj2.dislikes[0].time;
    });


    I did not get what you meant by earliest time. The above code sorts time in ascending order.



    NOTE: The above code does not handle edge cases where a property night be missing







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 23 '18 at 10:24

























    answered Nov 23 '18 at 10:02









    Royson

    3321311




    3321311












    • Mutates elements in array and is very inefficient to sort on every compare. Will also crash or bug out when user has no dislikes.
      – HMR
      Nov 23 '18 at 10:20




















    • Mutates elements in array and is very inefficient to sort on every compare. Will also crash or bug out when user has no dislikes.
      – HMR
      Nov 23 '18 at 10:20


















    Mutates elements in array and is very inefficient to sort on every compare. Will also crash or bug out when user has no dislikes.
    – HMR
    Nov 23 '18 at 10:20






    Mutates elements in array and is very inefficient to sort on every compare. Will also crash or bug out when user has no dislikes.
    – HMR
    Nov 23 '18 at 10:20















    2














    You can map the items and add a property to it containing the earliest dislike and then sort on that:






    const data = [{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511001,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511008,"timezoneOffset":-60,"year":118}}]},{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511011,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511028,"timezoneOffset":-60,"year":118}}]}];

    console.log(
    data
    //map and add newestDislike property
    .map((d) => ({
    ...d,
    //reduce and only takes the lowest time value
    newestDislike: (d.dislikes || ).reduce(
    (result, item) =>
    item.createDate.time < result
    ? item.createDate.time
    : result,
    Infinity, //defaults to infinity (if no dislikes)
    ),
    }))
    .sort((a, b) => a.newestDislike - b.newestDislike),
    );





    If the dislikes in the user are already sorted by oldest date first then you can skip the map and reduce part. If a user can have empty dislikes or undefined then make sure you use a getter function with a default so your code won't crash:



    //gets a nested prop from object or returns defaultValue
    const get = (o = {}, path, defaultValue) => {
    const recur = (o, path, defaultValue) => {
    if (o === undefined) return defaultValue;
    if (path.length === 0) return o;
    if (!(path[0] in o)) return defaultValue;
    return recur(o[path[0]], path.slice(1), defaultValue);
    };
    return recur(o, path, defaultValue);
    };
    console.log(
    data.sort(
    (a, b) =>
    get(
    a,
    ['dislikes', 0, 'createDate', 'time'],
    Infinity,
    ) -
    get(
    b,
    ['dislikes', 0, 'createDate', 'time'],
    Infinity,
    ),
    ),
    );





    share|improve this answer



















    • 1




      Good answer that handles undefined and other checks
      – Kruthika C S
      Nov 23 '18 at 11:40
















    2














    You can map the items and add a property to it containing the earliest dislike and then sort on that:






    const data = [{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511001,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511008,"timezoneOffset":-60,"year":118}}]},{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511011,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511028,"timezoneOffset":-60,"year":118}}]}];

    console.log(
    data
    //map and add newestDislike property
    .map((d) => ({
    ...d,
    //reduce and only takes the lowest time value
    newestDislike: (d.dislikes || ).reduce(
    (result, item) =>
    item.createDate.time < result
    ? item.createDate.time
    : result,
    Infinity, //defaults to infinity (if no dislikes)
    ),
    }))
    .sort((a, b) => a.newestDislike - b.newestDislike),
    );





    If the dislikes in the user are already sorted by oldest date first then you can skip the map and reduce part. If a user can have empty dislikes or undefined then make sure you use a getter function with a default so your code won't crash:



    //gets a nested prop from object or returns defaultValue
    const get = (o = {}, path, defaultValue) => {
    const recur = (o, path, defaultValue) => {
    if (o === undefined) return defaultValue;
    if (path.length === 0) return o;
    if (!(path[0] in o)) return defaultValue;
    return recur(o[path[0]], path.slice(1), defaultValue);
    };
    return recur(o, path, defaultValue);
    };
    console.log(
    data.sort(
    (a, b) =>
    get(
    a,
    ['dislikes', 0, 'createDate', 'time'],
    Infinity,
    ) -
    get(
    b,
    ['dislikes', 0, 'createDate', 'time'],
    Infinity,
    ),
    ),
    );





    share|improve this answer



















    • 1




      Good answer that handles undefined and other checks
      – Kruthika C S
      Nov 23 '18 at 11:40














    2












    2








    2






    You can map the items and add a property to it containing the earliest dislike and then sort on that:






    const data = [{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511001,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511008,"timezoneOffset":-60,"year":118}}]},{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511011,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511028,"timezoneOffset":-60,"year":118}}]}];

    console.log(
    data
    //map and add newestDislike property
    .map((d) => ({
    ...d,
    //reduce and only takes the lowest time value
    newestDislike: (d.dislikes || ).reduce(
    (result, item) =>
    item.createDate.time < result
    ? item.createDate.time
    : result,
    Infinity, //defaults to infinity (if no dislikes)
    ),
    }))
    .sort((a, b) => a.newestDislike - b.newestDislike),
    );





    If the dislikes in the user are already sorted by oldest date first then you can skip the map and reduce part. If a user can have empty dislikes or undefined then make sure you use a getter function with a default so your code won't crash:



    //gets a nested prop from object or returns defaultValue
    const get = (o = {}, path, defaultValue) => {
    const recur = (o, path, defaultValue) => {
    if (o === undefined) return defaultValue;
    if (path.length === 0) return o;
    if (!(path[0] in o)) return defaultValue;
    return recur(o[path[0]], path.slice(1), defaultValue);
    };
    return recur(o, path, defaultValue);
    };
    console.log(
    data.sort(
    (a, b) =>
    get(
    a,
    ['dislikes', 0, 'createDate', 'time'],
    Infinity,
    ) -
    get(
    b,
    ['dislikes', 0, 'createDate', 'time'],
    Infinity,
    ),
    ),
    );





    share|improve this answer














    You can map the items and add a property to it containing the earliest dislike and then sort on that:






    const data = [{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511001,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511008,"timezoneOffset":-60,"year":118}}]},{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511011,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511028,"timezoneOffset":-60,"year":118}}]}];

    console.log(
    data
    //map and add newestDislike property
    .map((d) => ({
    ...d,
    //reduce and only takes the lowest time value
    newestDislike: (d.dislikes || ).reduce(
    (result, item) =>
    item.createDate.time < result
    ? item.createDate.time
    : result,
    Infinity, //defaults to infinity (if no dislikes)
    ),
    }))
    .sort((a, b) => a.newestDislike - b.newestDislike),
    );





    If the dislikes in the user are already sorted by oldest date first then you can skip the map and reduce part. If a user can have empty dislikes or undefined then make sure you use a getter function with a default so your code won't crash:



    //gets a nested prop from object or returns defaultValue
    const get = (o = {}, path, defaultValue) => {
    const recur = (o, path, defaultValue) => {
    if (o === undefined) return defaultValue;
    if (path.length === 0) return o;
    if (!(path[0] in o)) return defaultValue;
    return recur(o[path[0]], path.slice(1), defaultValue);
    };
    return recur(o, path, defaultValue);
    };
    console.log(
    data.sort(
    (a, b) =>
    get(
    a,
    ['dislikes', 0, 'createDate', 'time'],
    Infinity,
    ) -
    get(
    b,
    ['dislikes', 0, 'createDate', 'time'],
    Infinity,
    ),
    ),
    );





    const data = [{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511001,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511008,"timezoneOffset":-60,"year":118}}]},{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511011,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511028,"timezoneOffset":-60,"year":118}}]}];

    console.log(
    data
    //map and add newestDislike property
    .map((d) => ({
    ...d,
    //reduce and only takes the lowest time value
    newestDislike: (d.dislikes || ).reduce(
    (result, item) =>
    item.createDate.time < result
    ? item.createDate.time
    : result,
    Infinity, //defaults to infinity (if no dislikes)
    ),
    }))
    .sort((a, b) => a.newestDislike - b.newestDislike),
    );





    const data = [{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511001,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511008,"timezoneOffset":-60,"year":118}}]},{"dislikes":[{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511011,"timezoneOffset":-60,"year":118}},{"createDate":{"date":11,"day":0,"hours":18,"minutes":15,"month":10,"seconds":11,"time":1541956511028,"timezoneOffset":-60,"year":118}}]}];

    console.log(
    data
    //map and add newestDislike property
    .map((d) => ({
    ...d,
    //reduce and only takes the lowest time value
    newestDislike: (d.dislikes || ).reduce(
    (result, item) =>
    item.createDate.time < result
    ? item.createDate.time
    : result,
    Infinity, //defaults to infinity (if no dislikes)
    ),
    }))
    .sort((a, b) => a.newestDislike - b.newestDislike),
    );






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 23 '18 at 10:24

























    answered Nov 23 '18 at 10:01









    HMR

    13.5k113898




    13.5k113898








    • 1




      Good answer that handles undefined and other checks
      – Kruthika C S
      Nov 23 '18 at 11:40














    • 1




      Good answer that handles undefined and other checks
      – Kruthika C S
      Nov 23 '18 at 11:40








    1




    1




    Good answer that handles undefined and other checks
    – Kruthika C S
    Nov 23 '18 at 11:40




    Good answer that handles undefined and other checks
    – Kruthika C S
    Nov 23 '18 at 11:40











    2














    //Supply the array you've metioned as the argument users to the below method, sortDislikesForAllUsers 
    let sortDislikesForAllUsers = function(users) {
    return users.map(user => {
    return {
    dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
    }
    })
    }
    //Supply the array returned in the above method as input to the below method, sortUsers
    let sortUsers = function(arrayOfSortedDislikesPerUser) {
    return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
    }

    let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
    let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
    console.log(finalSortedArray);



    In the below snippet,
    sortDislikesForAllUsers This method sorts the dislikes for individual
    users



    sortUsers This method sorts the users based on the first dislike time
    of the sorted dislikes array obtained from the above method




    Simple :)




    Run the below snippet. You can directly copy paste it in your code!







        let users = [{
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511001,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511008,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    },
    {
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511011,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511028,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    }]

    let sortDislikesForAllUsers = function(users) {
    return users.map(user => {
    return {
    dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
    }
    })
    }

    let sortUsers = function(arrayOfSortedDislikesPerUser) {
    return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
    }

    let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
    let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
    console.log(finalSortedArray);





    EDIT: WRT to the comment by @HMR:
    1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array.
    let noRefCopy = new Array()
    noRefCopy = noRefCopy.concat(originalArr)

    Now, perform sorting on the copy and return the same.



    2. If you wanna have checks for undefined etc, sure you can.




    The above answer attempts to address the logic. Sure we can address the above 2 concerns if the question is really specific to them.




    Cheers,

    Kruthika






    share|improve this answer























    • Sort mutates the array so after executing sortDislikesForAllUsers you've changed the original array (usually not a good thing). What if a user has no dislikes, say dislikes is an empty array or even undefined for a user?
      – HMR
      Nov 23 '18 at 11:06










    • Thanks for the comment HMR. The points you mentioned can be effectively addressed. 1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array. let noRefCopy = new Array() noRefCopy = noRefCopy.concat(originalArr) Now, perform sorting on the copy and return the same. 2. If you wanna have checkes for undefined etc, sure you can. The above answer attempts to address the logic. Sure we can address the above 2 concerns. PS:If you say, creating copy is a space concern now, you must create copy if you wanna avoid mutation
      – Kruthika C S
      Nov 23 '18 at 11:29












    • user.dislikes.slice().sort(... would fix the mutation as well but a user without dislikes (empty array or undefined) would crash your code. To fix that you will need a getter (see second part of my answer)
      – HMR
      Nov 23 '18 at 11:35


















    2














    //Supply the array you've metioned as the argument users to the below method, sortDislikesForAllUsers 
    let sortDislikesForAllUsers = function(users) {
    return users.map(user => {
    return {
    dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
    }
    })
    }
    //Supply the array returned in the above method as input to the below method, sortUsers
    let sortUsers = function(arrayOfSortedDislikesPerUser) {
    return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
    }

    let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
    let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
    console.log(finalSortedArray);



    In the below snippet,
    sortDislikesForAllUsers This method sorts the dislikes for individual
    users



    sortUsers This method sorts the users based on the first dislike time
    of the sorted dislikes array obtained from the above method




    Simple :)




    Run the below snippet. You can directly copy paste it in your code!







        let users = [{
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511001,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511008,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    },
    {
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511011,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511028,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    }]

    let sortDislikesForAllUsers = function(users) {
    return users.map(user => {
    return {
    dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
    }
    })
    }

    let sortUsers = function(arrayOfSortedDislikesPerUser) {
    return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
    }

    let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
    let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
    console.log(finalSortedArray);





    EDIT: WRT to the comment by @HMR:
    1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array.
    let noRefCopy = new Array()
    noRefCopy = noRefCopy.concat(originalArr)

    Now, perform sorting on the copy and return the same.



    2. If you wanna have checks for undefined etc, sure you can.




    The above answer attempts to address the logic. Sure we can address the above 2 concerns if the question is really specific to them.




    Cheers,

    Kruthika






    share|improve this answer























    • Sort mutates the array so after executing sortDislikesForAllUsers you've changed the original array (usually not a good thing). What if a user has no dislikes, say dislikes is an empty array or even undefined for a user?
      – HMR
      Nov 23 '18 at 11:06










    • Thanks for the comment HMR. The points you mentioned can be effectively addressed. 1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array. let noRefCopy = new Array() noRefCopy = noRefCopy.concat(originalArr) Now, perform sorting on the copy and return the same. 2. If you wanna have checkes for undefined etc, sure you can. The above answer attempts to address the logic. Sure we can address the above 2 concerns. PS:If you say, creating copy is a space concern now, you must create copy if you wanna avoid mutation
      – Kruthika C S
      Nov 23 '18 at 11:29












    • user.dislikes.slice().sort(... would fix the mutation as well but a user without dislikes (empty array or undefined) would crash your code. To fix that you will need a getter (see second part of my answer)
      – HMR
      Nov 23 '18 at 11:35
















    2












    2








    2






    //Supply the array you've metioned as the argument users to the below method, sortDislikesForAllUsers 
    let sortDislikesForAllUsers = function(users) {
    return users.map(user => {
    return {
    dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
    }
    })
    }
    //Supply the array returned in the above method as input to the below method, sortUsers
    let sortUsers = function(arrayOfSortedDislikesPerUser) {
    return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
    }

    let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
    let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
    console.log(finalSortedArray);



    In the below snippet,
    sortDislikesForAllUsers This method sorts the dislikes for individual
    users



    sortUsers This method sorts the users based on the first dislike time
    of the sorted dislikes array obtained from the above method




    Simple :)




    Run the below snippet. You can directly copy paste it in your code!







        let users = [{
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511001,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511008,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    },
    {
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511011,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511028,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    }]

    let sortDislikesForAllUsers = function(users) {
    return users.map(user => {
    return {
    dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
    }
    })
    }

    let sortUsers = function(arrayOfSortedDislikesPerUser) {
    return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
    }

    let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
    let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
    console.log(finalSortedArray);





    EDIT: WRT to the comment by @HMR:
    1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array.
    let noRefCopy = new Array()
    noRefCopy = noRefCopy.concat(originalArr)

    Now, perform sorting on the copy and return the same.



    2. If you wanna have checks for undefined etc, sure you can.




    The above answer attempts to address the logic. Sure we can address the above 2 concerns if the question is really specific to them.




    Cheers,

    Kruthika






    share|improve this answer














    //Supply the array you've metioned as the argument users to the below method, sortDislikesForAllUsers 
    let sortDislikesForAllUsers = function(users) {
    return users.map(user => {
    return {
    dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
    }
    })
    }
    //Supply the array returned in the above method as input to the below method, sortUsers
    let sortUsers = function(arrayOfSortedDislikesPerUser) {
    return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
    }

    let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
    let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
    console.log(finalSortedArray);



    In the below snippet,
    sortDislikesForAllUsers This method sorts the dislikes for individual
    users



    sortUsers This method sorts the users based on the first dislike time
    of the sorted dislikes array obtained from the above method




    Simple :)




    Run the below snippet. You can directly copy paste it in your code!







        let users = [{
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511001,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511008,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    },
    {
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511011,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511028,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    }]

    let sortDislikesForAllUsers = function(users) {
    return users.map(user => {
    return {
    dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
    }
    })
    }

    let sortUsers = function(arrayOfSortedDislikesPerUser) {
    return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
    }

    let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
    let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
    console.log(finalSortedArray);





    EDIT: WRT to the comment by @HMR:
    1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array.
    let noRefCopy = new Array()
    noRefCopy = noRefCopy.concat(originalArr)

    Now, perform sorting on the copy and return the same.



    2. If you wanna have checks for undefined etc, sure you can.




    The above answer attempts to address the logic. Sure we can address the above 2 concerns if the question is really specific to them.




    Cheers,

    Kruthika






        let users = [{
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511001,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511008,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    },
    {
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511011,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511028,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    }]

    let sortDislikesForAllUsers = function(users) {
    return users.map(user => {
    return {
    dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
    }
    })
    }

    let sortUsers = function(arrayOfSortedDislikesPerUser) {
    return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
    }

    let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
    let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
    console.log(finalSortedArray);





        let users = [{
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511001,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511008,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    },
    {
    "dislikes": [
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511011,
    "timezoneOffset": -60,
    "year": 118
    },
    },
    {
    "createDate": {
    "date": 11,
    "day": 0,
    "hours": 18,
    "minutes": 15,
    "month": 10,
    "seconds": 11,
    "time": 1541956511028,
    "timezoneOffset": -60,
    "year": 118
    },
    }
    ],
    }]

    let sortDislikesForAllUsers = function(users) {
    return users.map(user => {
    return {
    dislikes: user.dislikes.sort((dislikeA, dislikeB) => ((dislikeA.createDate.time < dislikeB.createDate.time) ? -1 : (dislikeA.createDate.time > dislikeB.createDate.time) ? 1 : 0))
    }
    })
    }

    let sortUsers = function(arrayOfSortedDislikesPerUser) {
    return arrayOfSortedDislikesPerUser.sort((userA, userB) => ((userA.dislikes[0].createDate.time < userB.dislikes[0].createDate.time) ? -1 : (userA.dislikes[0].createDate.time > userB.dislikes[0].createDate.time) ? 1 : 0))
    }

    let arrayOfSortedDislikesPerUser = sortDislikesForAllUsers(users);
    let finalSortedArray = sortUsers(arrayOfSortedDislikesPerUser);
    console.log(finalSortedArray);






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 23 '18 at 11:44

























    answered Nov 23 '18 at 10:49









    Kruthika C S

    140112




    140112












    • Sort mutates the array so after executing sortDislikesForAllUsers you've changed the original array (usually not a good thing). What if a user has no dislikes, say dislikes is an empty array or even undefined for a user?
      – HMR
      Nov 23 '18 at 11:06










    • Thanks for the comment HMR. The points you mentioned can be effectively addressed. 1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array. let noRefCopy = new Array() noRefCopy = noRefCopy.concat(originalArr) Now, perform sorting on the copy and return the same. 2. If you wanna have checkes for undefined etc, sure you can. The above answer attempts to address the logic. Sure we can address the above 2 concerns. PS:If you say, creating copy is a space concern now, you must create copy if you wanna avoid mutation
      – Kruthika C S
      Nov 23 '18 at 11:29












    • user.dislikes.slice().sort(... would fix the mutation as well but a user without dislikes (empty array or undefined) would crash your code. To fix that you will need a getter (see second part of my answer)
      – HMR
      Nov 23 '18 at 11:35




















    • Sort mutates the array so after executing sortDislikesForAllUsers you've changed the original array (usually not a good thing). What if a user has no dislikes, say dislikes is an empty array or even undefined for a user?
      – HMR
      Nov 23 '18 at 11:06










    • Thanks for the comment HMR. The points you mentioned can be effectively addressed. 1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array. let noRefCopy = new Array() noRefCopy = noRefCopy.concat(originalArr) Now, perform sorting on the copy and return the same. 2. If you wanna have checkes for undefined etc, sure you can. The above answer attempts to address the logic. Sure we can address the above 2 concerns. PS:If you say, creating copy is a space concern now, you must create copy if you wanna avoid mutation
      – Kruthika C S
      Nov 23 '18 at 11:29












    • user.dislikes.slice().sort(... would fix the mutation as well but a user without dislikes (empty array or undefined) would crash your code. To fix that you will need a getter (see second part of my answer)
      – HMR
      Nov 23 '18 at 11:35


















    Sort mutates the array so after executing sortDislikesForAllUsers you've changed the original array (usually not a good thing). What if a user has no dislikes, say dislikes is an empty array or even undefined for a user?
    – HMR
    Nov 23 '18 at 11:06




    Sort mutates the array so after executing sortDislikesForAllUsers you've changed the original array (usually not a good thing). What if a user has no dislikes, say dislikes is an empty array or even undefined for a user?
    – HMR
    Nov 23 '18 at 11:06












    Thanks for the comment HMR. The points you mentioned can be effectively addressed. 1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array. let noRefCopy = new Array() noRefCopy = noRefCopy.concat(originalArr) Now, perform sorting on the copy and return the same. 2. If you wanna have checkes for undefined etc, sure you can. The above answer attempts to address the logic. Sure we can address the above 2 concerns. PS:If you say, creating copy is a space concern now, you must create copy if you wanna avoid mutation
    – Kruthika C S
    Nov 23 '18 at 11:29






    Thanks for the comment HMR. The points you mentioned can be effectively addressed. 1. It mutates the original array. Yes. If you want to avoid mutation, you must create a copy of the sent array. let noRefCopy = new Array() noRefCopy = noRefCopy.concat(originalArr) Now, perform sorting on the copy and return the same. 2. If you wanna have checkes for undefined etc, sure you can. The above answer attempts to address the logic. Sure we can address the above 2 concerns. PS:If you say, creating copy is a space concern now, you must create copy if you wanna avoid mutation
    – Kruthika C S
    Nov 23 '18 at 11:29














    user.dislikes.slice().sort(... would fix the mutation as well but a user without dislikes (empty array or undefined) would crash your code. To fix that you will need a getter (see second part of my answer)
    – HMR
    Nov 23 '18 at 11:35






    user.dislikes.slice().sort(... would fix the mutation as well but a user without dislikes (empty array or undefined) would crash your code. To fix that you will need a getter (see second part of my answer)
    – HMR
    Nov 23 '18 at 11:35













    1














    Something like as follows (with lodash.js)



    _.each(users, (u) => { u.dislikes = _.sortBy(u.dislikes, 'createdDate.time'); });
    users = _.sortBy(users, 'dislikes[0].createdDate.time');





    share|improve this answer


























      1














      Something like as follows (with lodash.js)



      _.each(users, (u) => { u.dislikes = _.sortBy(u.dislikes, 'createdDate.time'); });
      users = _.sortBy(users, 'dislikes[0].createdDate.time');





      share|improve this answer
























        1












        1








        1






        Something like as follows (with lodash.js)



        _.each(users, (u) => { u.dislikes = _.sortBy(u.dislikes, 'createdDate.time'); });
        users = _.sortBy(users, 'dislikes[0].createdDate.time');





        share|improve this answer












        Something like as follows (with lodash.js)



        _.each(users, (u) => { u.dislikes = _.sortBy(u.dislikes, 'createdDate.time'); });
        users = _.sortBy(users, 'dislikes[0].createdDate.time');






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 23 '18 at 10:01









        Andrey

        1164




        1164






























            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53444228%2fsort-array-by-childs-child%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

            What visual should I use to simply compare current year value vs last year in Power BI desktop

            How to ignore python UserWarning in pytest?

            Alexandru Averescu