代码之家  ›  专栏  ›  技术社区  ›  user1063287

如何对数组对象和数组子集进行排序

  •  0
  • user1063287  · 技术社区  · 6 年前

    架构

    var my_array = [ 
    {
        "title": "a",
        "pinned": {
            "status": "true",
            "order": "1"
        }
    },
    {
        "title": "d",
        "pinned": {
            "status": "false",
            "order": "n/a"
        }
    },
    {
        "title": "c",
        "pinned": {
            "status": "true",
            "order": "0"
        }
    },
    {
        "title": "b",
        "pinned": {
            "status": "false",
            "order": "n/a"
        }
    }
    ];
    

    对象排序依据 title 按字母顺序,
    除非他们有 pinned 的状态 true ,

    pinned.order 价值观。

    一个示例场景是一个论坛,它有按日期排序的帖子,但在顶部也有按定义顺序排序的粘性帖子。

    因此,原始模式将显示为:

    [ 
    {// i am at the top, because i have a pinned status of true and order of 0  
        "title": "c",
        "pinned": {
            "status": "true",
            "order": "0"
        }
    },
    {// i am second from the top, because i have a pinned status of true and order of 1  
        "title": "a",
        "pinned": {
            "status": "true",
            "order": "1"
        }
    },
    {// i follow in alphabetical order 
        "title": "b",
        "pinned": {
            "status": "false",
            "order": "n/a"
        }
    },
    {// i follow in alphabetical order 
        "title": "d",
        "pinned": {
            "status": "false",
            "order": "n/a"
        }
    }
    ]
    

    我试过的

    my_array.sort(function(a, b) {
        return a.pinned.order.localeCompare(b.pinned.order) || a.title.localeCompare(b.title);
    });
    

    基于这个答案:

    https://stackoverflow.com/a/45741804

    我也试过。。。

    我考虑过根据 pinned.status

    var my_array = [ 
    {
        "title": "a",
        "pinned": {
            "status": "true",
            "order": "1"
        }
    },
    {
        "title": "d",
        "pinned": {
            "status": "false",
            "order": "n/a"
        }
    },
    {
        "title": "c",
        "pinned": {
            "status": "true",
            "order": "0"
        }
    },
    {
        "title": "b",
        "pinned": {
            "status": "false",
            "order": "n/a"
        }
    }
    ];
    
    
    var my_subset = [];
    
    for (var i = 0; i < my_array.length; i++) {
    
        if (my_array[i].pinned.status === "true") {
            // add to subset
            my_subset.push(my_array[i]);
            // remove from original array
            my_array.splice(i, 1);
        }
    
    }
    
    // sort "pruned" original array alphabetically
    my_array.sort(function(a, b) {
        return a.title.localeCompare(b.title);
    });
    
    // sort subset array by pinned.order
    my_subset.sort(function(a, b) {
        return a.pinned.order.localeCompare(b.pinned.order, undefined, { numeric: true });
    });
    
    // prepend subset to original array
    var new_array = my_subset.concat(my_array);
    
    // array is sorted as desired
    console.log(new_array);
    
    4 回复  |  直到 6 年前
        1
  •  2
  •   user1063287    6 年前

    首先通过将数字字符串设置为数字,将布尔字符串设置为布尔值来修复数据:

    for (const item of my_array) {
        item.pinned.status = JSON.parse(item.pinned.status);
        item.pinned.order = Number(item.pinned.order);
    }
    

    现在你不必把它们当作字符串来比较了。否则,你的方法基本上是好的,你只是忘记了一个最重要的指标,一个项目是否应该去顶部:它的 pinned.status . 首先比较,以便任何固定的项位于任何未固定的项之前。

    my_array.sort(function(a, b) {
        return -(a.pinned.status - b.pinned.status) // reverse: true before false
        || (a.pinned.status // equal to b.pinned.status
          ? a.pinned.order - b.pinned.order
          : a.title.localeCompare(b.title));
    });
    

    var my_array = [{
        "title": "a",
        "pinned": {
          "status": true,
          "order": 1
        }
      },
      {
        "title": "d",
        "pinned": {
          "status": false,
          "order": 0
        }
      },
      {
        "title": "c",
        "pinned": {
          "status": true,
          "order": 0
        }
      },
      {
        "title": "b",
        "pinned": {
          "status": false,
          "order": 0
        }
      }
    ];
    
    my_array.sort(function(a, b) {
      return -(a.pinned.status - b.pinned.status) // reverse: true before false
        ||
        (a.pinned.status // equal to b.pinned.status
          ?
          a.pinned.order - b.pinned.order :
          a.title.localeCompare(b.title));
    });
    
    console.log(my_array);

    你也可以这样做

    my_array.sort(function(a, b) {
        return -(a.pinned.status - b.pinned.status) // reverse: true before false
        || a.pinned.order - b.pinned.order
        || a.title.localeCompare(b.title);
    });
    

    因为没有固定的项目具有相同的顺序( NaN

        2
  •  1
  •   Ankit    6 年前

    my_array.sort(function(a, b) {
        return a.title.localeCompare(b.title);
    }).sort(function(a, b) {
        return a.pinned.order.localeCompare(b.pinned.order)
    });
    
        3
  •  0
  •   Saeed    6 年前

    如果可以使用Lodash(Javascript实用程序库),则可以使用orderBy或sortBy:

    <script src="lodash.js"></script>
    

    使用orderBy排序:

    _.orderBy(my_array, [function(e) { return e.pinned.status}, 'title'], ['asc', 'asc']);
    

    more info on orderBy

        4
  •  0
  •   Saif Taher    6 年前

    给你:

    var my_array = [ 
    {
        "title": "a",
        "pinned": {
            "status": "true",
            "order": "1"
        }
    },
    {
        "title": "d",
        "pinned": {
            "status": "false",
            "order": "n/a"
        }
    },
    {
        "title": "c",
        "pinned": {
            "status": "true",
            "order": "0"
        }
    },
    {
        "title": "b",
        "pinned": {
            "status": "false",
            "order": "n/a"
        }
    }
    ];
    
    var trueArr = [];
    var falseArr = [];
    var titleArr = [];
    var tempArr = []
    
    for(var obj of my_array){
      if(obj.pinned.status == "true"){
        trueArr.push(obj);
      }else{
        falseArr.push(obj);
      }
    }
    
    function sortArr(arr){
      titleArr = [];
      tempArr = [];
    
      for(var obj of arr){
        titleArr.push(obj.title);
      }
      
      titleArr = titleArr.sort();
      
      for(var counter = 0; counter < arr.length; counter++){
        tempArr.push(null);
      }
      
      for(var obj of arr){
        tempArr[titleArr.indexOf(obj.title)] = obj;
      }
      for(counter = 0; counter < tempArr.length; counter++){
        arr[counter] = tempArr[counter];
      }
    }
    
    function addTrueFalseArr(arr){
      for (var obj of arr){
        my_array.push(obj)
      }
    }
    
    sortArr(trueArr);
    my_array = [];
    addTrueFalseArr(trueArr);
    sortArr(falseArr);
    addTrueFalseArr(falseArr);

    提取所有对象 pinned = true pinned = false . 然后它根据标题(按字母顺序)对两个数组进行排序,然后将原始数组设置为空数组--> [] ,然后附加 true false 项目。