【问题标题】:Sort array of objects by single key with date value通过具有日期值的单个键对对象数组进行排序
【发布时间】:2012-02-08 21:10:23
【问题描述】:

我有一个包含多个键值对的对象数组,我需要根据 'updated_at' 对它们进行排序:

[
    {
        "updated_at" : "2012-01-01T06:25:24Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-09T11:25:13Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-05T04:13:24Z",
        "foo" : "bar"
    }
]

最有效的方法是什么?

【问题讨论】:

    标签: javascript arrays object


    【解决方案1】:

    您可以使用Array.sort

    这是一个例子:

    var arr = [{
        "updated_at": "2012-01-01T06:25:24Z",
        "foo": "bar"
      },
      {
        "updated_at": "2012-01-09T11:25:13Z",
        "foo": "bar"
      },
      {
        "updated_at": "2012-01-05T04:13:24Z",
        "foo": "bar"
      }
    ]
    
    arr.sort(function(a, b) {
      var keyA = new Date(a.updated_at),
        keyB = new Date(b.updated_at);
      // Compare the 2 dates
      if (keyA < keyB) return -1;
      if (keyA > keyB) return 1;
      return 0;
    });
    
    console.log(arr);

    【讨论】:

    • 你不能使用keyA - keyB(或者可能是keyB - keyA)吗?日期对象有一个valueOf() 方法。
    • 如果您想根据键中的数值进行排序,那么这个 ES6 单线可能会有所帮助。 yourArr.sort((a, b) =&gt; a.yourNumericOrderingKey &gt; b.yourNumericOrderingKey)。在我的情况下,我必须根据主数组对象内部的 order 键进行排序。
    • 在 Chrome 移动版中不工作 >= 88.0.4324.152
    • 实际上不需要转换为日期对象,因为 ISO 格式的字母和时间顺序是相同的。所以你可以按字符串排序。只要所有值都采用正确的 ISO 格式(包括 UTC)
    • 在 2012 年,这是一个很好的答案。 2021年,看我下面的回答stackoverflow.com/questions/8837454/…
    【解决方案2】:

    我已经在这里回答了一个非常相似的问题:Simple function to sort an array of objects

    针对这个问题,我创建了这个小功能,可以满足您的需求:

    function sortByKey(array, key) {
        return array.sort(function(a, b) {
            var x = a[key]; var y = b[key];
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        });
    }
    

    【讨论】:

    • 在 Chrome 移动版中不工作 >= 88.0.4324.152
    【解决方案3】:

    Array.sort() 方法对数组的元素进行就地排序并返回该数组。小心Array.sort(),因为它不是Immutable。对于不可变排序,请使用immutable-sort

    此方法是使用您当前的 ISO 格式的updated_at 对数组进行排序。我们使用new Data(iso_string).getTime() 将 ISO 时间转换为 Unix 时间戳。 Unix 时间戳是一个我们可以做简单数学运算的数字。我们减去结果的第一个和第二个时间戳;如果第一个时间戳大于第二个,则返回数将为正数。如果第二个数字大于第一个,则返回值为负数。如果两者相同,则返回为零。这与内联函数所需的返回值完全一致。

    对于ES6

    arr.sort((a,b) => new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime());
    

    对于ES5

    arr.sort(function(a,b){ 
     return new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime();
    });
    

    如果您将 updated_at 更改为 unix 时间戳,您可以这样做:

    对于ES6

    arr.sort((a,b) => a.updated_at - b.updated_at);
    

    对于ES5

    arr.sort(function(a,b){ 
     return a.updated_at - b.updated_at;
    });
    

    在撰写本文时,现代浏览器不支持 ES6。要在现代浏览器中使用 ES6,请使用 babel 将代码转换为 ES5。期待浏览器在不久的将来支持 ES6。

    Array.sort() 应该收到 3 种可能结果之一的返回值:

    • 一个正数(第一项 > 第二项)
    • 负数(第一项
    • 如果两项相等则为0

    注意,内联函数的返回值可以是任何 正数或负数。 Array.Sort() 不关心什么 返回号码是。它只关心返回值是否为正, 负数或零。

    对于不可变排序:(ES6 中的示例)

    const sort = require('immutable-sort');
    const array = [1, 5, 2, 4, 3];
    const sortedArray = sort(array);
    

    你也可以这样写:

    import sort from 'immutable-sort';
    const array = [1, 5, 2, 4, 3];
    const sortedArray = sort(array);
    

    您看到的 import-from 是一种在 ES6 中包含 javascript 的新方法,它使您的代码看起来非常干净。我个人的最爱。

    不可变排序不会改变源数组,而是返回一个新数组。建议对不可变数据使用const

    【讨论】:

    • 另一个不可变的选择是使用 arr.slice().sort(...)
    • 在 Chrome 移动版中不工作 >= 88.0.4324.152
    【解决方案4】:

    这里是@David Brainer-Bankers answer 的略微修改版本,它按字符串或数字按字母顺序排序,并确保以大写字母开头的单词不会排在以小写字母开头的单词之上(例如“apple,Early”将按该顺序显示)。

    function sortByKey(array, key) {
        return array.sort(function(a, b) {
            var x = a[key];
            var y = b[key];
    
            if (typeof x == "string")
            {
                x = (""+x).toLowerCase(); 
            }
            if (typeof y == "string")
            {
                y = (""+y).toLowerCase();
            }
    
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        });
    }
    

    【讨论】:

    • 如果 a[key] 和 b[key] 不是两个字符串,建议的解决方案可能会出错。我建议将 y=y.toLowerCase() 替换为 y = (""+y).toLowerCase()
    • sort 可以接受任何正数或负数作为有效返回。你不需要额外的计算来强制它为 1,0,-1。您过于复杂了一个简单的返回值。最好不要添加不做任何事情的额外计算。
    【解决方案5】:

    使用下划线js或者lodash,

    var arrObj = [
        {
            "updated_at" : "2012-01-01T06:25:24Z",
            "foo" : "bar"
        },
        {
            "updated_at" : "2012-01-09T11:25:13Z",
            "foo" : "bar"
        },
        {
            "updated_at" : "2012-01-05T04:13:24Z",
            "foo" : "bar"
        }
    ];
    
    arrObj = _.sortBy(arrObj,"updated_at");
    

    _.sortBy() 返回一个新数组

    参考http://underscorejs.org/#sortBy 和 lodash 文档https://lodash.com/docs#sortBy

    【讨论】:

      【解决方案6】:

      借助 ES2015 支持,可以通过以下方式完成:

      foo.sort((a, b) => a.updated_at < b.updated_at ? -1 : 1)
      

      【讨论】:

      • 如果将
      • 如果 updated_at 是 ISO 时间,这将不起作用。此示例假定 Unix 时间戳,但 OP 以 ISO 格式发布数据。因此,您必须转换为 Unix 时间戳才能进行比较。这可以通过new Date(iso_str).getTime() 完成,这将返回一个 Unix 时间戳。
      【解决方案7】:

      数据导入

      [
          {
              "gameStatus": "1",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-20 11:32:04"
          },
          {
              "gameStatus": "0",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-19 18:08:24"
          },
          {
              "gameStatus": "2",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-19 18:35:40"
          },
          {
              "gameStatus": "0",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-19 10:42:53"
          },
          {
              "gameStatus": "2",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-20 10:54:09"
          },
          {
              "gameStatus": "0",
              "userId": "1a2fefb0-5ae2-47eb-82ff-d1b2cc27875a",
              "created_at": "2018-12-19 18:46:22"
          },
          {
              "gameStatus": "1",
              "userId": "7118ed61-d8d9-4098-a81b-484158806d21",
              "created_at": "2018-12-20 10:50:48"
          }
      ]
      

      FOR 升序

      arr.sort(function(a, b){
          var keyA = new Date(a.updated_at),
              keyB = new Date(b.updated_at);
          // Compare the 2 dates
          if(keyA < keyB) return -1;
          if(keyA > keyB) return 1;
          return 0;
      });
      

      升序示例

      [
          {
              "gameStatus": "0",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-19 10:42:53"
          },
          {
              "gameStatus": "0",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-19 18:08:24"
          },
          {
              "gameStatus": "2",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-19 18:35:40"
          },
          {
              "gameStatus": "0",
              "userId": "1a2fefb0-5ae2-47eb-82ff-d1b2cc27875a",
              "created_at": "2018-12-19 18:46:22"
          },
          {
              "gameStatus": "1",
              "userId": "7118ed61-d8d9-4098-a81b-484158806d21",
              "created_at": "2018-12-20 10:50:48"
          },
          {
              "gameStatus": "2",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-20 10:54:09"
          },
          {
              "gameStatus": "1",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-20 11:32:04"
          }
      ]
      

      FOR 降序

      arr.sort(function(a, b){
          var keyA = new Date(a.updated_at),
              keyB = new Date(b.updated_at);
          // Compare the 2 dates
          if(keyA > keyB) return -1;
          if(keyA < keyB) return 1;
          return 0;
      });
      

      描述顺序示例

      [
          {
              "gameStatus": "1",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-20 11:32:04"
          },
          {
              "gameStatus": "2",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-20 10:54:09"
          },
          {
              "gameStatus": "1",
              "userId": "7118ed61-d8d9-4098-a81b-484158806d21",
              "created_at": "2018-12-20 10:50:48"
          },
          {
              "gameStatus": "0",
              "userId": "1a2fefb0-5ae2-47eb-82ff-d1b2cc27875a",
              "created_at": "2018-12-19 18:46:22"
          },
          {
              "gameStatus": "2",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-19 18:35:40"
          },
          {
              "gameStatus": "0",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-19 18:08:24"
          },
          {
              "gameStatus": "0",
              "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
              "created_at": "2018-12-19 10:42:53"
          }
      ]
      

      【讨论】:

        【解决方案8】:

        作为This 答案的状态,您可以使用Array.sort

        arr.sort(function(a,b){return new Date(a.updated_at) - new Date(b.updated_at)})

        arr = [
            {
                "updated_at" : "2012-01-01T06:25:24Z",
                "foo" : "bar"
            },
            {
                "updated_at" : "2012-01-09T11:25:13Z",
                "foo" : "bar"
            },
            {
                "updated_at" : "2012-01-05T04:13:24Z",
                "foo" : "bar"
            }
        ];
        arr.sort(function(a,b){return new Date(a.updated_at) - new Date(b.updated_at)});
        console.log(arr);

        【讨论】:

          【解决方案9】:

          至于今天,@knowbody (https://stackoverflow.com/a/42418963/6778546) 和@Rocket Hazmat (https://stackoverflow.com/a/8837511/6778546) 的答案可以结合起来提供 ES2015 支持和正确的日期处理:

          arr.sort((a, b) => {
             const dateA = new Date(a.updated_at);
             const dateB = new Date(b.updated_at);
             return dateA - dateB;
          });
          

          【讨论】:

            【解决方案10】:

            您可以使用 Lodash 实用程序库来解决这个问题(它是一个非常高效的库):

            const data = [{
                "updated_at": "2012-01-01T06:25:24Z",
                "foo": "bar"
              },
              {
                "updated_at": "2012-01-09T11:25:13Z",
                "foo": "bar"
              },
              {
                "updated_at": "2012-01-05T04:13:24Z",
                "foo": "bar"
              }
            ]
            
            const ordered = _.orderBy(
              data,
              function(item) {
                return item.updated_at;
              }
            );
            
            console.log(ordered)
            &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"&gt;&lt;/script&gt;

            您可以在此处找到文档:https://lodash.com/docs/4.17.15#orderBy

            【讨论】:

              【解决方案11】:

              只是另一种更数学做同样事情但更短的方法:

              arr.sort(function(a, b){
                  var diff = new Date(a.updated_at) - new Date(b.updated_at);
                  return diff/(Math.abs(diff)||1);
              });
              

              或采用光滑的 lambda 箭头样式:

              arr.sort((a, b) => {
                  var diff = new Date(a.updated_at) - new Date(b.updated_at);
                  return diff/(Math.abs(diff)||1);
              });
              

              这个方法可以用任何数字输入来完成

              【讨论】:

              • 被低估的答案
              • 为什么要规范化diff? JS排序只关心结果的符号和零状态,而不关心实际值。 (docs)
              【解决方案12】:

              通过这个我们可以传递一个用于排序的键函数

              Array.prototype.sortBy = function(key_func, reverse=false){
                  return this.sort( (a, b) => {
                      var keyA = key_func(a),
                          keyB = key_func(b);
                      if(keyA < keyB) return reverse? 1: -1;
                      if(keyA > keyB) return reverse? -1: 1;
                      return 0;
                  }); 
              }
              

              那么例如如果我们有

              var arr = [ {date: "01/12/00", balls: {red: "a8",  blue: 10}},
                          {date: "12/13/05", balls: {red: "d6" , blue: 11}},
                          {date: "03/02/04", balls: {red: "c4" , blue: 15}} ]
              

              我们可以的

              arr.sortBy(el => el.balls.red)
              /* would result in
              [ {date: "01/12/00", balls: {red: "a8", blue: 10}},
                {date: "03/02/04", balls: {red: "c4", blue: 15}},
                {date: "12/13/05", balls: {red: "d6", blue: 11}} ]
              */
              

              arr.sortBy(el => new Date(el.date), true)   // second argument to reverse it
              /* would result in
              [ {date: "12/13/05", balls: {red: "d6", blue:11}},
                {date: "03/02/04", balls: {red: "c4", blue:15}},
                {date: "01/12/00", balls: {red: "a8", blue:10}} ]
              */
              

              arr.sortBy(el => el.balls.blue + parseInt(el.balls.red[1]))
              /* would result in
              [ {date: "12/13/05", balls: {red: "d6", blue:11}},    // red + blue= 17
                {date: "01/12/00", balls: {red: "a8", blue:10}},    // red + blue= 18
                {date: "03/02/04", balls: {red: "c4", blue:15}} ]   // red + blue= 19
              */
              

              【讨论】:

                【解决方案13】:

                我在 Typescript 中创建了一个排序函数,我们可以使用它来搜索对象数组中的字符串、日期和数字。它还可以对多个字段进行排序。

                export type SortType = 'string' | 'number' | 'date';
                export type SortingOrder = 'asc' | 'desc';
                
                export interface SortOptions {
                  sortByKey: string;
                  sortType?: SortType;
                  sortingOrder?: SortingOrder;
                }
                
                
                class CustomSorting {
                    static sortArrayOfObjects(fields: SortOptions[] = [{sortByKey: 'value', sortType: 'string', sortingOrder: 'desc'}]) {
                        return (a, b) => fields
                          .map((field) => {
                            if (!a[field.sortByKey] || !b[field.sortByKey]) {
                              return 0;
                            }
                
                            const direction = field.sortingOrder === 'asc' ? 1 : -1;
                
                            let firstValue;
                            let secondValue;
                
                            if (field.sortType === 'string') {
                              firstValue = a[field.sortByKey].toUpperCase();
                              secondValue = b[field.sortByKey].toUpperCase();
                            } else if (field.sortType === 'number') {
                              firstValue = parseInt(a[field.sortByKey], 10);
                              secondValue = parseInt(b[field.sortByKey], 10);
                            } else if (field.sortType === 'date') {
                              firstValue = new Date(a[field.sortByKey]);
                              secondValue = new Date(b[field.sortByKey]);
                            }
                            return firstValue > secondValue ? direction : firstValue < secondValue ? -(direction) : 0;
                
                          })
                          .reduce((pos, neg) => pos ? pos : neg, 0);
                      }
                    }
                }
                

                用法:

                const sortOptions = [{
                      sortByKey: 'anyKey',
                      sortType: 'string',
                      sortingOrder: 'asc',
                    }];
                
                arrayOfObjects.sort(CustomSorting.sortArrayOfObjects(sortOptions));
                

                【讨论】:

                  【解决方案14】:

                  按 ISO 格式的日期排序可能会很昂贵,除非您将客户端限制为最新和最好的浏览器,这些浏览器可以通过日期解析字符串来创建正确的时间戳。

                  如果您确定您的输入,并且您知道它将始终是 yyyy-mm-ddThh:mm:ss 和 GMT (Z),您可以提取每个成员的数字并像整数一样比较它们

                  array.sort(function(a,b){
                      return a.updated_at.replace(/\D+/g,'')-b.updated_at.replace(/\D+/g,'');
                  });
                  

                  如果日期的格式可能不同,您可能需要为 ISO 挑战者添加一些内容:

                  Date.fromISO: function(s){
                      var day, tz,
                      rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
                      p= rx.exec(s) || [];
                      if(p[1]){
                          day= p[1].split(/\D/).map(function(itm){
                              return parseInt(itm, 10) || 0;
                          });
                          day[1]-= 1;
                          day= new Date(Date.UTC.apply(Date, day));
                          if(!day.getDate()) return NaN;
                          if(p[5]){
                              tz= (parseInt(p[5], 10)*60);
                              if(p[6]) tz+= parseInt(p[6], 10);
                              if(p[4]== '+') tz*= -1;
                              if(tz) day.setUTCMinutes(day.getUTCMinutes()+ tz);
                          }
                          return day;
                      }
                      return NaN;
                  }
                  if(!Array.prototype.map){
                      Array.prototype.map= function(fun, scope){
                          var T= this, L= T.length, A= Array(L), i= 0;
                          if(typeof fun== 'function'){
                              while(i< L){
                                  if(i in T){
                                      A[i]= fun.call(scope, T[i], i, T);
                                  }
                                  ++i;
                              }
                              return A;
                          }
                      }
                  }
                  }
                  

                  【讨论】:

                    【解决方案15】:

                    为了完整起见,这里是 sortBy 的一个可能的简短通用实现:

                    function sortBy(list, keyFunc) {
                      return list.sort((a,b) => keyFunc(a) - keyFunc(b));
                    }
                    
                    sortBy([{"key": 2}, {"key": 1}], o => o["key"])
                    

                    请注意,这使用了就地排序的数组排序方法。 对于副本,您可以使用 arr.concat() 或 arr.slice(0) 或类似方法来创建副本。

                    【讨论】:

                      【解决方案16】:
                      • 使用Array.sort() 对数组进行排序
                      • 使用spread operator () 克隆数组以使函数成为纯函数
                      • 按所需键排序 (updated_at)
                      • 将日期字符串转换为date object
                      • Array.sort() 的工作原理是从当前项和下一项中减去两个属性,如果它是一个可以执行心律失常操作的数字/对象
                      const input = [
                        {
                          updated_at: '2012-01-01T06:25:24Z',
                          foo: 'bar',
                        },
                        {
                          updated_at: '2012-01-09T11:25:13Z',
                          foo: 'bar',
                        },
                        {
                          updated_at: '2012-01-05T04:13:24Z',
                          foo: 'bar',
                        }
                      ];
                      
                      const sortByUpdatedAt = (items) => [...items].sort((itemA, itemB) => new Date(itemA.updated_at) - new Date(itemB.updated_at));
                      
                      const output = sortByUpdatedAt(input);
                      
                      console.log(input);
                      /*
                      [ { updated_at: '2012-01-01T06:25:24Z', foo: 'bar' }, 
                        { updated_at: '2012-01-09T11:25:13Z', foo: 'bar' }, 
                        { updated_at: '2012-01-05T04:13:24Z', foo: 'bar' } ]
                      */
                      console.log(output)
                      /*
                      [ { updated_at: '2012-01-01T06:25:24Z', foo: 'bar' }, 
                        { updated_at: '2012-01-05T04:13:24Z', foo: 'bar' }, 
                        { updated_at: '2012-01-09T11:25:13Z', foo: 'bar' } ]
                      */
                      

                      【讨论】:

                        【解决方案17】:

                        我来晚了一点,但在 2021 年,正确答案是使用 Intl.Collatorupdated_at 是一个 ISO-8601 字符串,因此可以作为字符串排序。转换为 Date 是浪费时间,因此手动执行 if 比较以返回 0、1 或 -1。

                        const arr = [
                          {
                            "updated_at": "2012-01-01T06:25:24Z",
                            "foo": "bar"
                          },
                          {
                            "updated_at": "2012-01-09T11:25:13Z",
                            "foo": "bar"
                          },
                          {
                            "updated_at": "2012-01-05T04:13:24Z",
                            "foo": "bar"
                          }
                        ];
                        
                        const { compare } = Intl.Collator('en-US');
                        arr.sort((a, b) => compare(a.updated_at, b.updated_at));
                        

                        Intl.Collator 返回一个函数,该函数可用作#Array.sortcompareFunction。因为我们正在对一个对象进行排序,所以我们调用 compare 并使用我们想要排序的键的值。

                        请注意,如果我们对字符串数组进行排序,我们可以简单地这样做:

                        arr.sort(compare);
                        

                        还请注意,正如其他人指出的那样,sort 将改变原始数组。如果这是不可取的,您可能需要先克隆它。在 2021 年,您可以这样做:

                        [...arr].sort((a, b) => compare(a.updated_at, b.updated_at));
                        

                        【讨论】:

                        • 这是截至 2021 年 12 月 14 日唯一对我有用的! (对于那些用头撞墙的人)
                        【解决方案18】:

                        我面临同样的事情,所以我用一个通用的原因来处理这个问题,并为此构建了一个函数:

                        //example:
                        //array: [{name: 'idan', workerType: '3'}, {name: 'stas', workerType: '5'}, {name: 'kirill', workerType: '2'}]
                        //keyField: 'workerType'
                        // keysArray: ['4', '3', '2', '5', '6']
                        
                        sortByArrayOfKeys = (array, keyField, keysArray) => {
                            array.sort((a, b) => {
                                const aIndex = keysArray.indexOf(a[keyField])
                                const bIndex = keysArray.indexOf(b[keyField])
                                if (aIndex < bIndex) return -1;
                                if (aIndex > bIndex) return 1;
                                return 0;
                            })
                        }
                        

                        【讨论】:

                          【解决方案19】:

                          您可以创建一个闭包并以这种方式传递它 here is my example working

                          $.get('https://data.seattle.gov/resource/3k2p-39jp.json?$limit=10&$where=within_circle(incident_location, 47.594972, -122.331518, 1609.34)', 
                            function(responce) {
                          
                              var filter = 'event_clearance_group', //sort by key group name
                              data = responce; 
                          
                              var compare = function (filter) {
                                  return function (a,b) {
                                      var a = a[filter],
                                          b = b[filter];
                          
                                      if (a < b) {
                                          return -1;
                                      } else if (a > b) {
                                          return 1;
                                      } else {
                                          return 0;
                                      }
                                  };
                              };
                          
                              filter = compare(filter); //set filter
                          
                              console.log(data.sort(filter));
                          });
                          

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 2021-01-15
                            • 2017-04-19
                            • 2021-02-15
                            • 2021-12-24
                            • 1970-01-01
                            • 1970-01-01
                            • 2017-04-26
                            相关资源
                            最近更新 更多