gpt4 book ai didi

javascript - 如何有效地将稀疏数组重新排序为新的非稀疏数组

转载 作者:行者123 更新时间:2023-11-29 22:21:54 25 4
gpt4 key购买 nike

[我提前为问题的复杂性表示歉意……但是有什么好的问题是简单的呢?]

我负责管理一个大型(22 名成员)生产支持团队的待命名单。该列表是“全面升级”(列出所有团队成员),每月生成一次。由于靠近列表顶部的人被召集到隔夜问题(并且往往不可用),我们利用反向列表来创建我们的白天任务名册。

问题

经过不合理的时间、政治和争论(不要问),一个相当愚蠢的规则集被创建并同意生成这个花名册。生成每日任务花名册:

“在待命列表中向后移动,选择列表中的“偶数”排名,并将它们按降序排列在第一位。然后对“几率”进行相同的操作,将它们放在花名册上。”

所以,一个简单的例子:

待命:“1-Jack、2-Jim、3-Jane、4-John、5-Jill、6-Joe”花名册:“1-Joe、2-John、3-Jim、4-Jill、3-Jane、1-Jack”

主要问题在于,由于休假、PTO、其他任务等时间,on-call 列表很少(可能有空位)。所以一个更真实的例子可能是:

待命:“1-Jack、3-Jane、4-John、6-Joe”花名册:“1-Joe、2-John、3-Jane、4-Jack

真实名单是22人。在任何给定的一天,我们平均有 17 或 18 个可用。失踪人员不会影响随叫随到 - 你只是继续移动到下一个最高 - 但他们让在名册规则内工作很痛苦。

当前(不雅)的解决方案

目前我有这种工作蛮力风格。我首先创建一个代表待命对象的数组,其中每个对象都有一个人的姓名和待命等级。 (我确实突然想到,我可以通过创建一个仅包含索引代表实际排名的名称的稀疏数组来简化这一点……但我认为这不会改变问题)。

然后我从倒数第一循环遍历数组两次:首先收集偶数排名(通过获取排名的模数)并将它们插入新数组,然后收集赔率:

                       // Get the Current Oncall 
var Oncall = new Array();
for ( var iCnt = 1; iCnt <= 22; iCnt++ ) {
var CurOncall = DataRows[Cnt].getAttribute("ows_OnCall" + iCnt);
if ( CurOncall != null ) {
Oncall[Oncall.length] = {"Name":CurOncall, "Rank": iCnt};
};
};
// Get the Current Roster
var Roster = new Array();
// Add the "evens"
for ( var iCnt = Oncall.length - 1; iCnt >= 0; iCnt-- ) {
// Get the Current Incident Rank
if ( Oncall[iCnt].Rank % 2 == 0 ) {
Roster[Roster.length] = Oncall[iCnt].Name;
};
}
// Add the "odds"
for ( var iCnt = Oncall.length - 1; iCnt >= 0; iCnt-- ) {
// Get the Current Incident Rank
if ( Oncall[iCnt].Rank % 2 != 0 ) {
Roster[Roster.length] = Oncall[iCnt].Name;
};
}

请注意,此片段存在于一个更大的循环中(我正在循环一周的数据,这只是一天)。 DataRows[Cnt] 是从 SharePoint 网络服务中提取的当天信息。

同样,这工作正常,但每天处理同一数据需要三个循环。

当前(损坏的)解决方案

我想做的是到达 poing,在那里我可以使用单个循环从 on-call 生成花名册。直接进入,我一直致力于将第二个两个循环合并为一个。假设 Oncall 数组的生成与上面相同,这是我目前的尝试(有点难看):

       var IncCnt = 1; 
for ( var Cnt = OnCall.length - 1; Cnt >= 0; Cnt-- ) {

// Get the Current Incident (Roster) Rank
if ( OnCall[Cnt].Rank % 2 == 0 ) {
CurIncRank = Math.ceil(IncCnt / 2);
} else {
CurIncRank = Math.ceil(IncCnt / 2) + Math.floor(OnCall.length / 2)
};

Roster[CurIncRank] = OnCall[Cnt].Name;
// Increase the Incident Cnt
IncCnt = IncCnt + 1;

};

这接近工作,但往往会重叠(用第一个“奇数”覆盖最后一个“偶数”)或在偶数和奇数之间留下间隙,具体取决于元素的稀疏性和总数。

结论

主要目标是在第一个循环中直接“即时”生成花名册,而不是创建一个特定的待命数组然后从中生成它 - 但目前我很乐意只获得第二个片段适用于所有情况。

我也对这可能无法工作的可能性持开放态度。也许不雅的规则集和不雅的数据的组合只需要蛮力方法。如果是这样的话,我宁愿在放弃之前从比我自己更好的程序员那里听到它。

提前致谢。随时要求任何澄清。

最佳答案

因此,如果我没看错的话,您有一个“onCall”对象数组,每个对象都包含一个名称和等级,如下所示:

var onCall = [
{
rank: 1,
name: 'Jack'
},
{
rank: 3,
name: 'Jill'
},
...
];

然后,您想要创建一个花名册数组,其中包含按降序排列的均匀排列的人,然后是按降序排列的奇数排列的人。如果这是正确的,那么下面的代码将产生这样一个数组:

for(var i = onCall.length-1; i >= 0; i--) {
person = onCall[i];
if(person.rank % 2 === 0) {
evens.push(person);
} else {
odds.push(person);
}
}
roster = evens.concat(odds);

你以相反的方式遍历数组一次。对于每个人,根据他们的排名将它们附加到“偶数”或“赔率”。最后,您只需将两个数组连接成一个新的“花名册”数组。

这是一个演示:

--- jsFiddle DEMO ---

很抱歉,这不是用您的特定变量名编写的,但如果这是您正在寻找的,它应该很容易更改以适应您的环境。

关于javascript - 如何有效地将稀疏数组重新排序为新的非稀疏数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11990323/

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