Javascript 使用嵌套属性对对象数组进行排序,其中某些属性未定义

标签 javascript sorting

我正在尝试实现一个排序函数,该函数接受对象数组并按属性或嵌套属性对它们进行排序。我在这里查看了大量问题,并对这个问题给出了很好的答案,但据我所知,它们都没有解释何时缺少嵌套属性。

例如,如果我对数组元素之一按 some_attributesome_attribute = undefined 进行排序,则相关元素将被移至数组的末尾/开头,正如我所料。如果我按 some_attribute.something_else 排序,当 some_attribute.something_else = undefined 时,我看到的函数响应不佳。

这是我尝试排序的数据结构示例:

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
    }
]

现在,如果我运行下面的代码,当我期望 [undefined, 2, 3, 5] 时,我会得到 [2, 3, 5, undefined] 结果>.

results.sortBy('twitter_link_click_count.total').map(function(x){return x.twitter_link_click_count.total})

在上面的代码片段中,sortBythis post 中的函数。 ,但是我也尝试使用 Underscore 的 _.sortBy 函数获得相同的结果。

工作代码

这是我根据 Oleg 的回答提出的解决方案:

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

这里的关键区别在于它生成一个 sortKey 数组,该数组可以用于 if/else 语句或迭代。我使用了 if/else,因为我的 sortKey 仅位于对象内部的 1 或 2 层深处。我还通过返回 0 而不是 true 来处理属性为 null 的情况。希望这对其他人有帮助。

最佳答案

请尝试以下脚本(此处使用下划线):

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>

关于Javascript 使用嵌套属性对对象数组进行排序,其中某些属性未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34644272/

相关文章:

javascript - JavaScript 中的排序函数在某些情况下无法给出正确的输出?

c++ - 如何在显示的代码中对一个类的两个数据成员数组进行排序

javascript - 即 10 : debug console (F12) changes behavior

javascript - 从 service worker 返回带有 JSON 的 Response 对象

javascript - AngularJS 的工厂设计模式,这是正确的方法吗?

javascript - jquery - .each() 的每次迭代增加超时间隔

javascript - textarea 中的 onkeyup 事件

java - 非法参数异常 : Comparison method violates it's general contract

mysql - 按升序获取表中的字母数字值

Python:按 "column"对列表进行排序