0

我一直在做一个项目,到目前为止 Stack Overflow 已经帮助我解决了一些问题,所以我非常感谢!

我的问题是这样的:

我有一个这样的数组:

var records:Object = {};

var arr:Array = [
records["nh"] = { medinc:66303, statename:"New Hampshire"},
records["ct"] = { medinc:65958, statename:"Connecticut"},
records["nj"] = { medinc:65173, statename:"New Jersey"},
records["md"] = { medinc:64596, statename:"Maryland"},

等等......适用于所有 50 个州。然后我对数组进行反向数字(降序)排序,如下所示:

arr.sortOn("medinc", Array.NUMERIC);
arr.reverse();

我可以调用记录的名称(即新泽西州的“nj”),然后从数组中记录上方和下方的数字位置获取值吗?

基本上,medinc 是美国各州的中等收入,我试图展示一个排名系统......例如,用户会点击 Texas,它会显示 Texas 的 medinc 值,以及排名在下一位的州和在数组中排名高一位的状态。

谢谢你的帮助!

4

4 回答 4

3

如果您知道对象,则可以使用 array.indexOf()。

var index:int = records.indexOf(records["nj"]);

var above:Object;
var below:Object;

if(index + 1 < records.length){ //make sure your not already at the top
   above = records[index+1];
}

if(index > 0){  //make sure your not already at the bottom
   below = records[index-1];
}
于 2012-08-29T23:58:06.157 回答
0

这并不是设置数据的好方法 - 输入过多(您一遍又一遍地重复“records”、“medinc”、“statename”,而您绝对可以避免它,例如:

var records:Array = [];
var states:Array = ["nh", "ct", "nj" ... ];
var statenames:Array = ["New Hampshire", "Connecticut", "New Jersey" ... ];
var medincs:Array = [66303, 65958, 65173 ... ];
var hash:Object = { };

function addState(state:String, medinc:int, statename:String, hash:Object):Object
{
    return hash[state] = { medinc: medinc, statename: statename };
}

for (var i:int; i < 50; i++)
{
    records[i] = addState(states[i], medincs[i], statenames[i], hash);
}

虽然您已经按照您的方式完成了它,但这并不是必需的,但这可以为您节省一些击键,如果您还没有...

现在,关于您的搜索问题 - 首先,确实,在搜索之前对数组进行排序是值得的,但是如果您需要根据排序参数的值来搜索数组,那么有一个更好的算法那。也就是说,如果给定示例中的数据,您的具体任务是找出收入是 65958 的状态,然后,知道数组是按收入排序的,您可以使用二分搜索

现在,对于具有 50 个状态的示例,除非您每秒执行数十万次,否则差异不会很明显,但总的来说,二分搜索将是可行的方法。

如果 Wiki 中的文章看起来太长而无法阅读;)二进制搜索背后的想法是,首先您猜测搜索的值恰好在数组的中间 - 您尝试该假设,如果您猜对了,则返回索引您刚刚找到,否则 - 您选择包含搜索值的间隔(剩余数组的一半)并这样做,直到您找到该值或检查相同的索引 - 这意味着找不到该值)。这将算法的渐近复杂度从 O(n) 降低到 O(log n)。

现在,如果你的目标是找到收入和状态之间的对应关系,但它如何与其他状态扩展并不重要(即数组中的索引并不重要),你可以有另一个哈希表,其中收入将是关键,状态信息对象将是价值,使用我上面的例子:

function addState(state:String, medinc:int, statename:String, 
    hash:Object, incomeHash:Object):Object
{
    return incomeHash[medinc] = 
        hash[state] = { medinc: medinc, statename: statename };
}

然后incomeHash[medinc]将在 O(1) 时间内按收入为您提供状态。

于 2012-08-30T09:37:30.463 回答
0

你真的需要记录来散列吗?

如果没有,您可以简单地将键移动到记录字段并将记录更改为简单数组:

var records: Array = new Array();
records.push({ short: "nh", medinc:66303, statename:"New Hampshire"}),
records.push({ short: "ct", medinc:65958, statename:"Connecticut"}),
....

这使您有机会为 State 创建类,将 Array 更改为 Vector 并使所有这些类型安全,这总是好的。

如果你真的需要这些键,你可以像现在一样添加上面的对象(带有“短”字段)(也许使用一些帮助函数,这将有助于避免输入两次短名称,比如 addState(records, data ) { 记录 [data.short] = 数据 })。

最后,您还可以将这些记录保存在两个对象(或一个对象和一个数组或任何您需要的东西)中。如果您将创建一次状态对象并将引用保存在数组/对象/向量中,这不会很昂贵。如果您经常需要按不同键排序的状态,那将是个好主意。

于 2012-08-30T02:04:23.323 回答
0

我认为这是基于我对您的数据的理解的答案。

var index:int = arr.indexOf(records["nh"]);

这将为您提供被点击的记录的索引,然后找到下面和上面的索引:

var clickedRecord:Object = arr[index]
var higherRecord:Object = arr[index++]
var lowerRecord:Object = arr[index--]

希望这能回答你的问题

于 2012-08-30T00:03:35.190 回答