【问题标题】:How to sort a JS object of objects?如何对对象的JS对象进行排序?
【发布时间】:2012-12-26 12:52:23
【问题描述】:

我在 PHP 中构建了一个对象,使用 JSON_encode 函数并通过 ajax 将其作为 JSON 字符串发送到我的 JS 脚本。然后我将它转换回一个对象。我遇到的问题是我想保持对象最初创建的顺序。请看这张图片,一旦我将它放入 JS 中,对象的样子:

当我创建对象时,它按客户字段的字母顺序排序。以 A 开头的客户名称将排在第一位,B 排在第二位,依此类推。如您所见,现在,对象的第一个元素为以 S 开头的客户。看起来它以某种方式自动按顶层的键排序对象,它是一个整数,所以我明白为什么会这样。

所以我想做的是重新排序这个对象,以便所有子对象都按字母顺序按customer 字段排序。这可能吗?如果是这样,我该怎么做?

谢谢!

【问题讨论】:

  • 您是否遍历了要检查的对象? Chrome 开发工具不会按实际迭代顺序显示对象属性。请记住,对象没有定义的标准跨浏览器迭代顺序,但这些通常遵循添加属性的顺序。
  • 不,不可能对对象进行排序。对象总是未排序的。
  • 您最好让每一行都成为array 中的object 条目;然后,您可以按客户名称对array 进行排序。 您不能依赖 JavaScript 中对象的迭代顺序。
  • 是的,最好的办法是按照@Mathletics 的建议将对象转换为数组。
  • 只是添加到@Mathletics 的建议。拥有数组后(我们称其为 json_array),您可以通过以下方式对其进行排序:json_array.sort(function(a, b){return a.customer > b.customer? 1: -1;});

标签: javascript json sorting jsobject


【解决方案1】:

我已更改 Fabricio Matée 答案以变得更加灵活并返回已排序的对象。

function alphabetical_sort_object_of_objects(data, attr) {
    var arr = [];
    for (var prop in data) {
        if (data.hasOwnProperty(prop)) {
            var obj = {};
            obj[prop] = data[prop];
            obj.tempSortName = data[prop][attr].toLowerCase();
            arr.push(obj);
        }
    }

    arr.sort(function(a, b) {
        var at = a.tempSortName,
            bt = b.tempSortName;
        return at > bt ? 1 : ( at < bt ? -1 : 0 );
    });

    var result = [];
    for (var i=0, l=arr.length; i<l; i++) {
        var obj = arr[i];
        delete obj.tempSortName;
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                var id = prop;
            }
        }
        var item = obj[id];
        result.push(item);
    }
    return result;
}

然后像这样调用函数

your_object = alphabetical_sort_object_of_objects(your_object, 'attribute_to_sort');

【讨论】:

  • 一点改进:在调用toLowerCase() 之前检查数据类型,以防万一它是number。在obj.tempSortName = data[prop][attr].toLowerCase();
【解决方案2】:

这可能是 JavaScript 对象和 JavaScript 数组之间的区别。对象更像哈希表,其中的键不按任何特定顺序排序,而数组是值的线性集合。

在您的后端,请确保您正在编码一个数组,而不是一个对象。检查最终编码的 JSON,如果您的对象集合被 {} 而不是 [] 包围,则它被编码为对象而不是数组。

您可能会遇到问题,因为看起来您正在尝试通过 ID 号访问对象,而这是您希望这些对象在最终数组中占据的索引,这会带来另一个问题,因为您可能没有当您只存储少量值时,不想要一个包含 40,000 个条目的数组。

如果您只想遍历对象,则应确保编码的是数组而不是对象。如果您想通过特定 ID 访问对象,您可能必须在客户端对对象进行排序(即从 JSON 响应中获取对象,然后创建另一个数组并将这些对象排序到其中,这样您就可以拥有已排序的对象,仍然可以通过 id 访问它们。

您可以通过 Google 轻松找到有效的排序算法(或使用以下来自 ELCas 的算法)。

【讨论】:

    【解决方案3】:

    这是一个通用迭代函数,它将所有对象推入一个数组中,并以不区分大小写的方式通过它们的customer 属性对它们进行排序,然后遍历排序后的数组:

    function iterate(data) {
      var arr = [];
      for (var prop in data) {
        if (data.hasOwnProperty(prop)) {
          var obj = {};
          obj[prop] = data[prop];
          obj.tempSortName = data[prop].customer.toLowerCase();
          arr.push(obj);
        }
      }
      arr.sort(function(a, b) {
        var at = a.tempSortName,
            bt = b.tempSortName;
        return at > bt ? 1 : ( at < bt ? -1 : 0 );
      });
    
      for (var i = 0, l = arr.length; i < l; i++) {
        var obj = arr[i];
        delete obj.tempSortName;
        console.log(obj);
        for (var prop in obj) {
          if (obj.hasOwnProperty(prop)) {
            var id = prop; //gets the obj "index" (id?)
          }
        }
        console.log(id);
        var item = obj[id];
        console.log(item.customer);
        //do stuff with item
      }
    }
    

    Fiddle

    【讨论】:

      【解决方案4】:
      sortObject(object){
          if(typeof object === 'object'){
              if(object instanceof Date){
                  return object;
              }
              if(object instanceof Array){
                  return object.map(element => this.sortObject(element));
              } else {
                  return Object.keys(object).sort().reduce((result, key) => {
                      if(object[key] && object[key] !== null) {
                          result[key] = this.sortObject(object[key]);
                      }
                      return result;
                  }, {});
              }
          }
          return object;
      }
      

      【讨论】:

        【解决方案5】:

        只需循环浏览您的数据并对其进行排序。我没有使用最高效的分拣机,但想法就在那里。

        var data = toArray(AJAX_Returned_JSON); // function to convert object to array
        var sortedData = null;
        
        for(var i=0; i<data.length - 1; i++){
          var temp = data[i];
          for(var j=i+1; j<data.length; j++){
            if(data[j].customer < temp.customer){
              temp = data[j];
            }
          }
        
          sortedData.push(temp);
        }
        

        【讨论】:

        • 忘记添加将数据转换为数组的行。
        • 这不是您将object 变成array 的方式。
        猜你喜欢
        • 2023-03-21
        • 2019-06-05
        • 2015-10-19
        • 2011-10-04
        • 1970-01-01
        • 1970-01-01
        • 2013-07-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多