I'm trying to implement a sorting function that takes in an array of objects and sorts them by an attribute or a nested attribute. I've looked at a ton of questions on here with good answers to this problem, but so far as I have seen, none of them account for when a nested attribute is missing.
For example, if I sort by some_attribute
and some_attribute = undefined
for one of my array elements, the element in question is bumped to the end/beginning of the array, as I would expect. If I sort by some_attribute.something_else
, the functions I've seen don't respond well when some_attribute.something_else = undefined
.
Here is a sample of my data structure I'm trying to sort:
results = [
{
id: 233,
post: "Test 944 AM http://frmply.co/1mA9G3L",
twitter_favorite_count: 0,
twitter_retweet_count: 2,
twitter_link_click_count: {
minute: null,
hour: null,
day: null,
week: null,
month: null,
total: 3
},
twitter_last_updated: "2015-12-28T21:11:27.425Z",
facebook_like_count: null,
facebook_share_count: 1,
facebook_comment_count: null,
facebook_link_click_count: {
minute: null,
hour: null,
day: null,
week: null,
month: null,
total: 1
},
facebook_last_updated: "2015-12-28T21:11:29.232Z",
linkedin_like_count: null,
linkedin_comment_count: null,
linkedin_link_click_count: {
minute: null,
hour: null,
day: null,
week: null,
month: null,
total: 0
},
linkedin_last_updated: "2015-12-28T21:11:29.905Z"
},
{
id: 232,
post: "Test 944 AM http://frmply.co/1mA9G3L",
twitter_favorite_count: null,
twitter_retweet_count: null,
twitter_link_click_count: {
minute: null,
hour: null,
day: null,
week: null,
month: null,
total: 5
},
twitter_last_updated: null,
facebook_like_count: null,
facebook_share_count: null,
facebook_comment_count: null,
facebook_link_click_count: { },
facebook_last_updated: null,
linkedin_like_count: null,
linkedin_comment_count: null,
linkedin_link_click_count: { },
linkedin_last_updated: null
},
{
id: 234,
post: "localhost test 1106am http://frmply.co/1RAYalE",
twitter_favorite_count: 0,
twitter_retweet_count: 0,
twitter_link_click_count: {
minute: null,
hour: null,
day: null,
week: null,
month: null,
total: 2
},
twitter_last_updated: "2016-01-06T18:40:21.388Z",
facebook_like_count: null,
facebook_share_count: null,
facebook_comment_count: null,
facebook_link_click_count: {
minute: null,
hour: null,
day: null,
week: null,
month: null,
total: 0
},
facebook_last_updated: "2015-12-29T16:07:39.042Z",
linkedin_like_count: null,
linkedin_comment_count: null,
linkedin_link_click_count: {
minute: null,
hour: null,
day: null,
week: null,
month: null,
total: 0
},
linkedin_last_updated: "2015-12-29T16:07:39.489Z"
},
{
id: 231,
post: "test",
twitter_favorite_count: null,
twitter_retweet_count: null,
twitter_link_click_count: { },
twitter_last_updated: null,
facebook_like_count: null,
facebook_share_count: null,
facebook_comment_count: null,
facebook_link_click_count: { },
facebook_last_updated: null,
linkedin_like_count: null,
linkedin_comment_count: null,
linkedin_link_click_count: { },
linkedin_last_updated: null
}
]
Now if I run the code below I get [2, 3, 5, undefined]
as a result when I would expect [undefined, 2, 3, 5]
.
results.sortBy('twitter_link_click_count.total').map(function(x){return x.twitter_link_click_count.total})
In the snippet above, sortBy
is a function from this post , however I've also tried using Underscore's _.sortBy
function with identical results.
Working Code
Here is the solution I came up with based off Oleg's answer:
var sortKey = attribute.split('.');
var sortBy = function(results, sortKey) {
return _.sortBy(results, function(item) {
if(sortKey.length === 1) {
return item[sortKey[0]] || 0;
} else {
return item[sortKey[0]][sortKey[1]] || 0;
};
});
};
The key difference here is that it generates a sortKey
array, which can be used an an if/else statement or iterated over. I used an if/else since my sortKey
is only ever 1 or 2 layers deep inside my object. I also handled cases where my attribute is null
by returning 0
instead of true
. Hope this helps someone else.
Please try the following script (used Underscore there):
results = [ { id: 233, post: "Test 944 AM http://frmply.co/1mA9G3L", twitter_favorite_count: 0, twitter_retweet_count: 2, twitter_link_click_count: { minute: null, hour: null, day: null, week: null, month: null, total: 3 }, twitter_last_updated: "2015-12-28T21:11:27.425Z", facebook_like_count: null, facebook_share_count: 1, facebook_comment_count: null, facebook_link_click_count: { minute: null, hour: null, day: null, week: null, month: null, total: 1 }, facebook_last_updated: "2015-12-28T21:11:29.232Z", linkedin_like_count: null, linkedin_comment_count: null, linkedin_link_click_count: { minute: null, hour: null, day: null, week: null, month: null, total: 0 }, linkedin_last_updated: "2015-12-28T21:11:29.905Z" }, { id: 232, post: "Test 944 AM http://frmply.co/1mA9G3L", twitter_favorite_count: null, twitter_retweet_count: null, twitter_link_click_count: { minute: null, hour: null, day: null, week: null, month: null, total: 5 }, twitter_last_updated: null, facebook_like_count: null, facebook_share_count: null, facebook_comment_count: null, facebook_link_click_count: { }, facebook_last_updated: null, linkedin_like_count: null, linkedin_comment_count: null, linkedin_link_click_count: { }, linkedin_last_updated: null }, { id: 234, post: "localhost test 1106am http://frmply.co/1RAYalE", twitter_favorite_count: 0, twitter_retweet_count: 0, twitter_link_click_count: { minute: null, hour: null, day: null, week: null, month: null, total: 2 }, twitter_last_updated: "2016-01-06T18:40:21.388Z", facebook_like_count: null, facebook_share_count: null, facebook_comment_count: null, facebook_link_click_count: { minute: null, hour: null, day: null, week: null, month: null, total: 0 }, facebook_last_updated: "2015-12-29T16:07:39.042Z", linkedin_like_count: null, linkedin_comment_count: null, linkedin_link_click_count: { minute: null, hour: null, day: null, week: null, month: null, total: 0 }, linkedin_last_updated: "2015-12-29T16:07:39.489Z" }, { id: 231, post: "test", twitter_favorite_count: null, twitter_retweet_count: null, twitter_link_click_count: { }, twitter_last_updated: null, facebook_like_count: null, facebook_share_count: null, facebook_comment_count: null, facebook_link_click_count: { }, facebook_last_updated: null, linkedin_like_count: null, linkedin_comment_count: null, linkedin_link_click_count: { }, linkedin_last_updated: null } ]; document.getElementById('output').innerHTML = JSON.stringify(_.sortBy(results, function(item) { return item.twitter_link_click_count.total || true; }).map(function(x){return x.twitter_link_click_count.total}));
<script src="http://underscorejs.org/underscore-min.js"></script> <pre id="output"></pre>
results = results.filter(function (a) {
return !!((a.twitter_link_click_count || {}).total)
}).sort(function(a, b){
return (a.twitter_link_click_count || {}).total > (b.twitter_link_click_count || {}).total
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.