Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/464.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用另一个键上的对象数组,而不会干扰JavaScript中以前的排序(部分排序)_Javascript_Arrays_Sorting - Fatal编程技术网

使用另一个键上的对象数组,而不会干扰JavaScript中以前的排序(部分排序)

使用另一个键上的对象数组,而不会干扰JavaScript中以前的排序(部分排序),javascript,arrays,sorting,Javascript,Arrays,Sorting,我有这样一个对象数组: var booksArray = [ {Id:1,Rate:5,Price:200,Name:"History"}, {Id:2,Rate:5,Price:150,Name:"Geographic"}, {Id:3,Rate:1,Price:75,Name:"Maths"}, {Id:4,Rate:2,Price:50,Name:"Statistics"}, {Id:5,Rate:3,Price:120,Name:"Drawin

我有这样一个对象数组:

var booksArray = [  
    {Id:1,Rate:5,Price:200,Name:"History"},
    {Id:2,Rate:5,Price:150,Name:"Geographic"},
    {Id:3,Rate:1,Price:75,Name:"Maths"},
    {Id:4,Rate:2,Price:50,Name:"Statistics"},
    {Id:5,Rate:3,Price:120,Name:"Drawing"},
    {Id:6,Rate:2,Price:100,Name:"Arts"},
    {Id:7,Rate:3,Price:110,Name:"Chemistry"},
    {Id:8,Rate:4,Price:160,Name:"Biology"},
    {Id:9,Rate:4,Price:90,Name:"Software Engineering"},
    {Id:10,Rate:4,Price:80,Name:"Algorithm"},
    {Id:11,Rate:1,Price:85,Name:"Urdu"},
    {Id:12,Rate:1,Price:110,Name:"International Relations"},
    {Id:13,Rate:1,Price:120,Name:"Physics"},
    {Id:14,Rate:3,Price:230,Name:"Electronics"},
    {Id:15,Rate:3,Price:250,Name:"Jihad"},
    {Id:16,Rate:3,Price:200,Name:"Functional Programming"},
    {Id:17,Rate:2,Price:190,Name:"Computer Science"},
    {Id:18,Rate:2,Price:50,Name:"Problem solving Techniques"},
    {Id:19,Rate:6,Price:150,Name:"C#"},
    {Id:20,Rate:7,Price:250,Name:"ASP.Net"}
]
[
    {Id:12,Rate:1,Price:110,Name:"International Relations"},
    {Id:3,Rate:1,Price:75,Name:"Maths"},
    {Id:13,Rate:1,Price:120,Name:"Physics"},
    {Id:11,Rate:1,Price:85,Name:"Urdu"},
    {Id:6,Rate:2,Price:100,Name:"Arts"},
    {Id:17,Rate:2,Price:190,Name:"Computer Science"},
    {Id:18,Rate:2,Price:50,Name:"Problem solving Techniques"},
    {Id:4,Rate:2,Price:50,Name:"Statistics"},
    {Id:7,Rate:3,Price:110,Name:"Chemistry"},
    {Id:5,Rate:3,Price:120,Name:"Drawing"},
    {Id:14,Rate:3,Price:230,Name:"Electronics"},
    {Id:16,Rate:3,Price:200,Name:"Functional Programming"},
    {Id:15,Rate:3,Price:250,Name:"Jihad"},
    {Id:10,Rate:4,Price:80,Name:"Algorithm"},
    {Id:8,Rate:4,Price:160,Name:"Biology"},
    {Id:9,Rate:4,Price:90,Name:"Software Engineering"},
    {Id:2,Rate:5,Price:150,Name:"Geographic"},
    {Id:1,Rate:5,Price:200,Name:"History"},
    {Id:19,Rate:6,Price:150,Name:"C#"},
    {Id:20,Rate:7,Price:250,Name:"ASP.Net"}
]
我使用此功能对其进行排序:

function sortBy(key, reverse) {
    var moveSmaller = reverse ? 1 : -1;
    var moveLarger = reverse ? -1 : 1;
    return function(a, b) {
        if (a[key] < b[key]) {
            return moveSmaller;
        }

        if (a[key] > b[key]) {
            return moveLarger;
        }
        return 0;
    };
} 

booksArray.sort(sortBy('Rate', false))
console.log(JSON.stringify(booksArray))
您可以看到它在
Rate
字段上进行排序,这很好。现在,我想再次使用数组的各个部分,而不干扰
速率排序
。我需要这样的输出:

var booksArray = [  
    {Id:1,Rate:5,Price:200,Name:"History"},
    {Id:2,Rate:5,Price:150,Name:"Geographic"},
    {Id:3,Rate:1,Price:75,Name:"Maths"},
    {Id:4,Rate:2,Price:50,Name:"Statistics"},
    {Id:5,Rate:3,Price:120,Name:"Drawing"},
    {Id:6,Rate:2,Price:100,Name:"Arts"},
    {Id:7,Rate:3,Price:110,Name:"Chemistry"},
    {Id:8,Rate:4,Price:160,Name:"Biology"},
    {Id:9,Rate:4,Price:90,Name:"Software Engineering"},
    {Id:10,Rate:4,Price:80,Name:"Algorithm"},
    {Id:11,Rate:1,Price:85,Name:"Urdu"},
    {Id:12,Rate:1,Price:110,Name:"International Relations"},
    {Id:13,Rate:1,Price:120,Name:"Physics"},
    {Id:14,Rate:3,Price:230,Name:"Electronics"},
    {Id:15,Rate:3,Price:250,Name:"Jihad"},
    {Id:16,Rate:3,Price:200,Name:"Functional Programming"},
    {Id:17,Rate:2,Price:190,Name:"Computer Science"},
    {Id:18,Rate:2,Price:50,Name:"Problem solving Techniques"},
    {Id:19,Rate:6,Price:150,Name:"C#"},
    {Id:20,Rate:7,Price:250,Name:"ASP.Net"}
]
[
    {Id:12,Rate:1,Price:110,Name:"International Relations"},
    {Id:3,Rate:1,Price:75,Name:"Maths"},
    {Id:13,Rate:1,Price:120,Name:"Physics"},
    {Id:11,Rate:1,Price:85,Name:"Urdu"},
    {Id:6,Rate:2,Price:100,Name:"Arts"},
    {Id:17,Rate:2,Price:190,Name:"Computer Science"},
    {Id:18,Rate:2,Price:50,Name:"Problem solving Techniques"},
    {Id:4,Rate:2,Price:50,Name:"Statistics"},
    {Id:7,Rate:3,Price:110,Name:"Chemistry"},
    {Id:5,Rate:3,Price:120,Name:"Drawing"},
    {Id:14,Rate:3,Price:230,Name:"Electronics"},
    {Id:16,Rate:3,Price:200,Name:"Functional Programming"},
    {Id:15,Rate:3,Price:250,Name:"Jihad"},
    {Id:10,Rate:4,Price:80,Name:"Algorithm"},
    {Id:8,Rate:4,Price:160,Name:"Biology"},
    {Id:9,Rate:4,Price:90,Name:"Software Engineering"},
    {Id:2,Rate:5,Price:150,Name:"Geographic"},
    {Id:1,Rate:5,Price:200,Name:"History"},
    {Id:19,Rate:6,Price:150,Name:"C#"},
    {Id:20,Rate:7,Price:250,Name:"ASP.Net"}
]
在这里,您可以看到它是按
速率
以及
名称
排序的

为什么我不能一次性使用多个键进行排序?因为我正在创建一个函数,它对对象数组进行排序,并且可以多次调用

例如:

myarray.order('Rate') // single sort
myarray.order('Rate').order('Name') // multiple sort
我可以在函数中使用更多参数来跟踪数组是否已排序


只是为了好玩:这里有一个通用的分类器,用于在一个对象数组中选择多个级别的字段值

语法

XSort().create([arrOfObjects])
  .orderBy(
        {key: [keyname], [descending=0/1] }, 
        {key: [keyname], [descending=0/1]},
        ... );
有关使用
booksArray
的示例,请参见

function XSort() {
    const multiSorter = sortKeys => {
      if (!sortKeys || sortKeys[0].constructor !== Object) {
        throw new TypeError("Provide at least one {key: [keyname]} to sort on");
      }

      return function (val0, val1) {
        for (let sortKey of sortKeys) {
          const v0 = sortKey.key instanceof Function 
            ? sortKey.key(val0) : val0[sortKey.key];
          const v1 = sortKey.key instanceof Function 
            ? sortKey.key(val1) : val1[sortKey.key];
          const isString = v0.constructor === String || v1.constructor === String;
          const compare = sortKey.descending ?
            isString ? v1.toLowerCase().localeCompare(v0.toLowerCase()) : v1 - v0 :
            isString ? v0.toLowerCase().localeCompare(v1.toLowerCase()) : v0 - v1;
          if ( compare !== 0 ) { return compare; }
        }
      };
    }
    const Sorter = function (array) {
      this.array = array;
    };

    Sorter.prototype = {
      orderBy: function(...sortOns) {
        return this.array.slice().sort(multiSorter(sortOns));
      },
    };

    return {
      create: array => new Sorter(array)
    };
}

假设已经有按速率排序的bookArray。可以使用以下命令在第二级对其进行排序。可以更好地进行微调,以便于使用

var arr = bookArray;
var firstSortKey = 'Rate';
var secondSortKey = 'Name';
var count = 0 ;
var firstSortValue = arr[count][firstSortKey];

for(var i=count+1; i<arr.length; i++){
     if(arr[i][firstSortKey]!==firstSortValue){
         var data = arr.slice(count, i);
         data = data.sort(function(a, b){
             return a[secondSortKey]>b[secondSortKey];
         });
         var argsArray = [count, i-count];
         argsArray.push.apply(argsArray, data);
         Array.prototype.splice.apply(arr, argsArray);
         count = i;
         firstSortValue =  arr[i][firstSortKey];
     }
}
var-arr=bookArray;
var firstSortKey='费率';
var secondSortKey='Name';
var计数=0;
var firstSortValue=arr[count][firstSortKey];

对于(var i=count+1;i

通过
函数更改您的
排序以接受密钥数组。类似于:

function sortBy(keys, reverse) {
    var moveSmaller = reverse ? 1 : -1;
    var moveLarger = reverse ? -1 : 1;
    var key = keys.shift();

    return function(a, b) {
        if (a[key] < b[key]) {
            return moveSmaller;
        }

        if (a[key] > b[key]) {
            return moveLarger;
        }
        return keys.length ? (sortBy(keys, reverse))(a, b) : 0;
    };
} 

booksArray.sort(sortBy(['Rate', 'Name'], false))
功能排序(按键,反转){
var=反向?1:-1;
var=反向?-1:1;
var key=keys.shift();
返回函数(a,b){
如果(a[键]b[键]){
回报率较大;
}
返回键。长度?(按(键,反向)排序)(a,b):0;
};
} 
booksArray.sort(排序方式(['Rate','Name'],false))

(未经测试,JSFIDLE对我不利)

您想先按
速率
排序,然后按
名称
排序吗?就像SQL中的
按速率排序,名称
?排序是独立进行的,不知道需要保留前面的排序。有什么好处吗?我认为可能是重复的。也许可以看看这是一项相当大的工作。尽管如此,我还是喜欢这种方法我会尝试优化它。不,这不是我所需要的,我想避免。正如你所看到的,我已经提到了我的标准