按孩子的孩子排序数组

时间:2018-11-23 09:49:59

标签: javascript arrays sorting

情况是:我有一个对象数组,其中每个对象都有一个对象数组。数组如下所示:

[
    {
        "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
                },
            }
        ],
    }
]

因此,我想按time的不喜欢程度对用户和不喜欢的对象进行排序。因此,最早厌恶的用户将是第一个,而最早厌恶的用户将在每个用户的dislikes数组中排名第一。我相信我必须做多种事情,但是我该怎么做呢?

4 个答案:

答案 0 :(得分:2)

您可以映射项目并向其中添加包含最早不喜欢的属性,然后对其进行排序:

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),
);

如果已经按照最早的日期对用户的不喜欢进行了排序,那么您可以跳过地图并减少部分。如果用户可能有空的不喜欢或未定义的内容,请确保使用默认的getter函数,这样您的代码就不会崩溃:

//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,
      ),
  ),
);

答案 1 :(得分: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);
  

在以下代码段中,
   sortDislikesForAllUsers 这种方法可以对个人的不喜欢进行排序   用户

     

sortUsers 该方法根据用户的第一次不喜欢时间对用户进行排序   以上方法获得的排序的不喜欢数组的元素

简单:)

  

运行以下代码段。您可以直接复制粘贴到您的代码中!

    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);

编辑:@HMR对评论进行WRT
1。它会改变原始数组。是。如果要避免突变,则必须创建已发送数组的副本。 let noRefCopy = new Array() noRefCopy = noRefCopy.concat(originalArr)
现在,对副本进行排序并返回副本。

2。如果您想检查未定义的等,请确定。

  

以上答案试图解决逻辑问题。如果问题确实是针对他们的,我们当然可以解决以上两个问题。

干杯,
克鲁西卡

答案 2 :(得分:1)

如下所示(使用lodash.js)

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

答案 3 :(得分:1)

检查下面的代码。这将使您可以根据时间进行排序:

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;
});

最早的时间我没听懂你的意思。上面的代码按时间升序排序。

注意::上面的代码无法处理缺少财产之夜的极端情况