gpt4 book ai didi

javascript - 按属性或函数值对 javascript 数组进行排序

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:30:26 26 4
gpt4 key购买 nike

我有一个包含原始值和计算值的数组。我希望能够根据原始值或其中一个计算值的结果对数组进行动态排序。直到运行时才知道实际需要的排序。

我整理了以下示例 (plunker here) 来演示情况和可行的解决方案*。我想知道如何改进这个...具体来说,使用:

Array.prototype.sortBy = function (property) {
return this.sort(mySort(property));
};

复制自 this stackoverflow 响应 - Ege Özcan 特别指出

//Please don't just copy-paste this code. 
//See the explanation at the end. A lot could break.

我想了解如何在不违反“A lot could break”警告(我不明白)的情况下对我的对象实现此排序算法。

*我喜欢 stackoverflow 的一个原因是,很好地构建问题的过程经常会引导您将问题简化到(不一定是)解决方案本身。我开始这个问题无法根据属性或计算值进行排序。现在,我正在寻找对实现的验证/改进。

示例:

var rawData = [
{ "Id": 3, "itemCount": 3531, "val1": 905, "val2": 172 },
{ "Id": 2, "itemCount": 3111, "val1": 799, "val2": 147 },
{ "Id": 4, "itemCount": 3411, "val1": 871, "val2": 199 },
{ "Id": 5, "itemCount": 3414, "val1": 892, "val2": 178 },
{ "Id": 1, "itemCount": 3182, "val1": 845, "val2": 155 }
];



function MyItem(item) {
var self = this;
for (var val in item) {
if (item.hasOwnProperty(val)) {
self[val] = item[val];
}
}
}

function extendMyItems() {
MyItem.prototype.computedOne = function () {
var input = this;
return input.itemCount / input.val1;
};

MyItem.prototype.computedTwo = function () {
var input = this;
return input.val1 * input.val2;
};
}

function getItems(input) {
var ret = [];
for (var i = 0; i < input.length; i++) {
var item = new MyItem(input[i]);
ret.push(item);
}

return ret;
}

function doIt() {

Array.prototype.sortBy = function (property) {
return this.sort(mySort(property));
};

extendMyItems();
var sortList = [{ "sortKey": "Id", "sortOrder": "asc" },
{ "sortKey": "val1", "sortOrder": "asc" },
{ "sortKey": "val2", "sortOrder": "desc" },
{ "sortKey": "computedOne", "sortOrder": "desc", "isComputed": true },
{ "sortKey": "Id", "sortOrder": "desc" },
{ "sortKey": "computedTwo", "sortOrder": "asc", "isComputed": true }];

// get the array of MyItem
var myItems = getItems(rawData);

for (var k = 0; k < sortList.length; k++) {
myItems.sortBy(sortList[k]);
// process the sorted items here (ranking/scoring, etc)
for (var p = 0; p < myItems.length; p++) {
console.log('Id: ' + myItems[p].Id + ' val1: ' + myItems[p].val1 + ' val2: ' + myItems[p].val2 + ' c1: ' + myItems[p].computedOne() + ' c2: ' + myItems[p].computedTwo());
}

}

function mySort(srt) {
var so = srt.sortOrder == 'asc' ? 1 : -1;
var key = srt.sortKey;
var result = 0;
console.log(srt.sortKey + ' ' + srt.sortOrder + ':');

return function (a, b) {
if (srt.isComputed) {
// this seems like a hack - is there a better way to switch between property and function value????
result = (a[key]() < b[key]()) ? -1 : (a[key]() > b[key]()) ? 1 : 0;
} else {
result = (a[key] < b[key]) ? -1 : (a[key] > b[key]) ? 1 : 0;
}

return result * so;
};

}
}

最佳答案

大多数人认为扩展原生对象(如 Array)是一种不好的做法。这就是你提到的帖子的意思。问题是您不知道这将如何影响其他脚本的行为。

这是一个场景示例,在操作数组原型(prototype)后,编写不当会导致问题。这是我在基于大型代码时遇到过的一个场景,它真的很难追踪:

function BadUseOfForLoop(){
//You should NEVER use a for in loop to iterate over an array
//although some people do this and it works until you extend Array
var arr = [1,2,3,4];
for (key in arr){
console.log(arr[key]);
}
}

BadUseOfForLoop();

console.log("Extend Array...");

Array.prototype.sortBy = function(){
return "Doesnt matter...";
};

BadUseOfForLoop();

输出:

1 
2
3
4
Extend Array...
1
2
3
4
function (){
return "Doesnt matter...";
}

http://jsfiddle.net/vTwRY/

为了避免这个警告,您可以做的一件事就是不扩展 Array 对象并创建一个帮助程序来为您做这件事。

var ArrayHelper = {
sortBy : function(arr, prop){
return function(){
var so = srt.sortOrder == 'asc' ? 1 : -1;
var key = srt.sortKey;
var result = 0;
console.log(srt.sortKey + ' ' + srt.sortOrder + ':');
return function (a, b) {
if (srt.isComputed) {
result = (a[key]() < b[key]()) ? -1 : (a[key]() > b[key]()) ? 1 : 0;
} else {
result = (a[key] < b[key]) ? -1 : (a[key] > b[key]) ? 1 : 0;
}
return result * so;
};
}
}
};

然后在您的代码中...

ArrayHelper.sortBy(myItems,sortList[k]);

代替

myItems.sortBy(sortList[k]);

Working demo

有关此主题的进一步阅读 Perfection Kills帖子讨论了扩展 native 对象是否是一个好主意,您会发现这不是一个简单的问题。上面,我提出了一个问题,这个问题没有在这篇博文中讨论,但确实会导致与其他代码的冲突。

关于javascript - 按属性或函数值对 javascript 数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17451925/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com