Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.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 - Fatal编程技术网

JavaScript数组排序/等额排序

JavaScript数组排序/等额排序,javascript,Javascript,在根据对象的属性值(本例中为“评级”)对对象数组进行排序后,如果这些值之间存在关联,如何关联每个对象的等级?下面是一个例子: //Should be tied for 1st Rank var obj1 = { name: "Person1", rating: 99 } //Should be 3rd Rank var obj2 = { name: "Person2", rating: 50 } //Should be 2nd Rank var obj3 = { nam

在根据对象的属性值(本例中为“评级”)对对象数组进行排序后,如果这些值之间存在关联,如何关联每个对象的等级?下面是一个例子:

//Should be tied for 1st Rank
var obj1 = { 
  name: "Person1",
  rating: 99
}

//Should be 3rd Rank
var obj2 = {
  name: "Person2",
  rating: 50
}

//Should be 2nd Rank
var obj3 = {
  name: "Person3",
  rating: 98
}

//Should be 4th Rank
var obj4 = {
  name: "Person4",
  rating: 0
}

//Should be tied for 1st Rank
var obj5 = {
  name: "Person5",
  rating: 99
}
就我所知:

var clients = [obj1, obj2, obj3, obj4, obj5];
var sorted = [];

for (var i = 0; i < clients.length; i++) {
  sorted.push(clients[i]);
}

sorted.sort(function(a, b) {
  return b.rating-a.rating;
});

如果希望在同一位置上有多条记录,可能应该使用额外的立即数组,有效地对元素进行分组

为了方便起见,我会用洛达斯,你应该知道

_.chain(clients).groupBy('rating').pairs().sortBy(0).reverse().pluck(1).value();
此时您失去了使用indexOf的能力,因此需要编写自己的getRank

再一次,在洛达斯的帮助下

// returns zero when no rank is found
var getRank = function(sortedArray, object) {
    return 1 + _.findIndex(sortedArray, function(list) {
        return _.contains(list, object);
    });
};

全功能小提琴:第二次尝试:虽然不是很好-我认为将排名划分为不同的属性,而不是依赖索引来查找排名是一种方法。当出现平局时,你就有了更清晰的操作方法。还在工作。将关注最佳解决方案

for(var i = 0; i < sorted.length; i++) {
    // original ranking
     sorted[i].rank = i + 1; 
for(变量i=0;i
}

函数sortRanking(){
对于(i=0;i

第一次尝试-在玩了一段时间后。以下是从原始逻辑添加的解决方案:

var clients = [o1, o2, o3, o4];
var sorted = [];

for (var i = 0; i < clients.length; i++)
sorted.push(clients[i]);

sorted.sort(function (a, b) {

return clients.rating - clients.rating;
});



function checkForTieAndRating(x) {

// x parameter for object of interest
// need to get the one in front to determine if it is tied
// get index of obj of interest
var indexOfInterest = clients.indexOf(x);
var indexOfBefore = indexOfCurrent -1;

// if obj of interest is ranked #1 then return
if(indexOfBefore < 0) {
return indexOfInterest + 1;
} else {
// get the actual object before this one so you can check rating. put in variable so you can compare.
var objBefore = clients[indexOfBefore];
var ratingOfObjBefore = objBefore.rating;
if(ratingOfObjBefore === x.rating)
  return "Tied for" + indexOfInterest;
 }

}


// check ranking and if tie
checkForTieAndRating(obj2);

// other issue going this route - would be to then 1) alter the objects ranking following the objs that are tied - to 

//Possible alternative solution: After working and about to submit it - I think it would be better to add a ranking property after the sort and manipulate the rankings from there if there are any tied.
var客户=[o1,o2,o3,o4];
var排序=[];
对于(变量i=0;i
创建了一个有效的解决方案,尽管很难看。感谢jamie在本文中使用的一些框架:

for (var i = 0; i < clients.length; i++) {
  sorted.push(clients[i]);
}

sorted.sort(function(a, b) {
  return b.rating-a.rating;
});

for(var i = 0; i < sorted.length; i++) {
    // original ranking
     sorted[i].rank = i + 1; 
}


function sortRanking() {
  for (var k = 0; k < sorted.length; k++) {
    for (var h = 1; h < sorted.length + 1; h++) {
      if (sorted[k+h] !== undefined) {
        if (sorted[k+h].tie !== true) {
          if (sorted[k].rating === sorted[h + k].rating) {
            sorted[k].rank = k + 1;
            sorted[h + k].rank = k + 1;
            sorted[k].tie = true;
            sorted[h + k].tie = true;
          }
        }
      }    
    }
  }
}

sortRanking();
alert("Rank: " + obj3.rank);
for(var i=0;i
我需要一段类似的代码来编写操作调度脚本。我使用了对象及其属性/键,它们可以有任何值,并且可以在需要时访问。另外,据我在一些文章中所读到的,在对象中搜索属性可能比在数组中搜索更快

下面的脚本有三个简单步骤:

  • 对值进行排序(对于脚本的其余部分,升序或降序并不重要)

  • 查找每个值的列组和出现次数

  • 使用步骤2中的数据将给定值替换为列组

  • 注意!下面的脚本不会输出重复的列组,而是为重复的值/元素增加列组

    function rankArrayElements( toBeRanked ) {
    
    // STEP 1
    var toBeRankedSorted = toBeRanked.slice().sort( function( a,b ) { return b-a; } ); // sort descending
    //var toBeRankedSorted = toBeRanked.slice().sort( function( a,b ) { return a-b; } ); // sort ascending
    
    var ranks = {}; // each value from the input array will become a key here and have a rank assigned
    var ranksCount = {}; // each value from the input array will become a key here and will count number of same elements
    
    // STEP 2
    for (var i = 0; i < toBeRankedSorted.length; i++) { // here we populate ranks and ranksCount
        var currentValue = toBeRankedSorted[ i ].toString();
    
        if ( toBeRankedSorted[ i ] != toBeRankedSorted[ i-1 ] ) ranks[ currentValue ] = i; // if the current value is the same as the previous one, then do not overwrite the rank that was originally assigned (in this way each unique value will have the lowest rank)
        if ( ranksCount[ currentValue ] == undefined ) ranksCount[ currentValue ] = 1; // if this is the first time we iterate this value, then set count to 1
        else ranksCount[ currentValue ]++; // else increment by one
    }
    
    var ranked = [];
    
    // STEP 3
    for (var i = toBeRanked.length - 1; i >= 0; i--) { // we need to iterate backwards because ranksCount starts with maximum values and decreases
        var currentValue = toBeRanked[i].toString();
    
        ranksCount[ currentValue ]--;
        if ( ranksCount[ currentValue ] < 0 ) { // a check just in case but in theory it should never fail
            console.error( "Negative rank count has been found which means something went wrong :(" );
            return false;
        }
        ranked[ i ] = ranks[ currentValue ]; // start with the lowest rank for that value...
        ranked[ i ] += ranksCount[ currentValue ]; // ...and then add the remaining number of duplicate values
    }
    
    return ranked;}
    
    函数rankArrayElements(TOBERNAKED){
    //第一步
    var toBeRankedSorted=toBeRanked.slice().sort(函数(a,b){return b-a;});//按降序排序
    //var toBeRankedSorted=toBeRanked.slice().sort(函数(a,b){return a-b;});//按升序排序
    var ranks={};//输入数组中的每个值在这里都将成为一个键,并分配一个秩
    var ranksCount={};//输入数组中的每个值都将成为此处的键,并将计算相同元素的数量
    //步骤2
    对于(var i=0;i=0;i--){//我们需要向后迭代,因为ranksCount从最大值开始,然后减少
    var currentValue=ToBernaked[i].toString();
    ranksCount[currentValue]--;
    如果(ranksCount[currentValue]<0){//只是以防万一,但理论上它永远不会失败
    错误(“发现了负秩计数,这意味着发生了一些问题
    
    for (var i = 0; i < clients.length; i++) {
      sorted.push(clients[i]);
    }
    
    sorted.sort(function(a, b) {
      return b.rating-a.rating;
    });
    
    for(var i = 0; i < sorted.length; i++) {
        // original ranking
         sorted[i].rank = i + 1; 
    }
    
    
    function sortRanking() {
      for (var k = 0; k < sorted.length; k++) {
        for (var h = 1; h < sorted.length + 1; h++) {
          if (sorted[k+h] !== undefined) {
            if (sorted[k+h].tie !== true) {
              if (sorted[k].rating === sorted[h + k].rating) {
                sorted[k].rank = k + 1;
                sorted[h + k].rank = k + 1;
                sorted[k].tie = true;
                sorted[h + k].tie = true;
              }
            }
          }    
        }
      }
    }
    
    sortRanking();
    alert("Rank: " + obj3.rank);
    
    function rankArrayElements( toBeRanked ) {
    
    // STEP 1
    var toBeRankedSorted = toBeRanked.slice().sort( function( a,b ) { return b-a; } ); // sort descending
    //var toBeRankedSorted = toBeRanked.slice().sort( function( a,b ) { return a-b; } ); // sort ascending
    
    var ranks = {}; // each value from the input array will become a key here and have a rank assigned
    var ranksCount = {}; // each value from the input array will become a key here and will count number of same elements
    
    // STEP 2
    for (var i = 0; i < toBeRankedSorted.length; i++) { // here we populate ranks and ranksCount
        var currentValue = toBeRankedSorted[ i ].toString();
    
        if ( toBeRankedSorted[ i ] != toBeRankedSorted[ i-1 ] ) ranks[ currentValue ] = i; // if the current value is the same as the previous one, then do not overwrite the rank that was originally assigned (in this way each unique value will have the lowest rank)
        if ( ranksCount[ currentValue ] == undefined ) ranksCount[ currentValue ] = 1; // if this is the first time we iterate this value, then set count to 1
        else ranksCount[ currentValue ]++; // else increment by one
    }
    
    var ranked = [];
    
    // STEP 3
    for (var i = toBeRanked.length - 1; i >= 0; i--) { // we need to iterate backwards because ranksCount starts with maximum values and decreases
        var currentValue = toBeRanked[i].toString();
    
        ranksCount[ currentValue ]--;
        if ( ranksCount[ currentValue ] < 0 ) { // a check just in case but in theory it should never fail
            console.error( "Negative rank count has been found which means something went wrong :(" );
            return false;
        }
        ranked[ i ] = ranks[ currentValue ]; // start with the lowest rank for that value...
        ranked[ i ] += ranksCount[ currentValue ]; // ...and then add the remaining number of duplicate values
    }
    
    return ranked;}
    
    function convertRanksToListOfElementIDs( ranked ) {  // elements with lower ranks will be first in the list
    
    var list = [];
    
    for (var rank = 0; rank < ranked.length; rank++) { // for each rank...
        var rankFound = false;
        for (var elementID = 0; elementID < ranked.length; elementID++) { // ...iterate the array...
            if ( ranked[ elementID ] == rank ) { // ...and find the rank
                if ( rankFound ) console.error( "Duplicate ranks found, rank = " + rank + ", elementID = " + elementID );
                list[ rank ] = elementID;
                rankFound = true;
            }
        }
        if ( !rankFound ) console.error( "No rank found in ranked, rank = " + rank );
    }
    
    return list;}
    
    function rank(arr) {
        var ret = [];
        var s = [];
        var i = 0;
        var _key_;
        for (_key_ in arr) {
            var v;
            v = arr[_key_];
            if (!s[v]) {
                s[v] = ++i;
            }
            ret.push( {
                'Mark': v,
                'Rank': s[v]
            });
        }
        return ret;
    }
    var marks = [ 
        65,
        41,
        38,
        38,
        37,
        37,
        92,
        84,
        84,
        84,
        83
    ];
    marks.sort(function(a, b) {
      return b-a;
    });
    var rank = rank(marks);
     console.log(rank);