我无法按照我希望的方式组织这些数据。在我的页面上,发生了一些我知道工作的事情......
- 某些 PHP 会输出多维关联数组。该数组的顶层是区域数组。每个区域都是时区的数组。
- 更多 PHP 创建第二个多维关联数组。该数组的顶层是区域数组。每个区域都是 UTC 偏移量的数组。
- 两个数组都是按照相同的顺序从相同的数据生成的。这意味着
$offsets["region"][0]
将基于与$timezones["region"][0]
相同的时区。 - 两个数组都编码为 JSON 并传递给我的 JavaScript。
我有以下 JavaScript 代码...
var tempCurrentTimezoneArray = timezoneArray[ $("select[name='region_selector']").val() ];
var tempCurrentOffsetArray = timezoneOffsetArray[ $("select[name='region_selector']").val() ];
var groupedTimezones = {};
var groupedOffsets = {};
for (counter = 0; counter < tempCurrentOffsetArray.length; counter++) {
significantOffset = tempCurrentOffsetArray[counter].substr(tempCurrentOffsetArray[counter].length - 2);
if (!(significantOffset in groupedTimezones)) {
groupedTimezones[significantOffset] = [];
groupedOffsets[significantOffset] = [];
}
groupedTimezones[significantOffset].push(tempCurrentTimezoneArray[counter]);
groupedOffsets[significantOffset].push(tempCurrentOffsetArray[counter]);
}
var offsetArray = [];
for (var property in groupedTimezones) {
if (!groupedTimezones.hasOwnProperty(property)) {
continue;
}
groupedTimezones[property].sort();
groupedOffsets[property].sort();
offsetArray.push(parseInt(property));
}
offsetArray.sort();
var currentTimezoneArray = [];
var currentOffsetArray = [];
for (counter = 0; counter < offsetArray.length; counter++) {
currentTimezoneArray = currentTimezoneArray.concat(groupedTimezones[offsetArray[counter]]);
currentOffsetArray = currentOffsetArray.concat(groupedOffsets[offsetArray[counter]]);
}
在前两行中,我删除了与页面上所选区域不相关的所有时区数据。这意味着我只剩下两个一维数组。任一数组的任何给定索引都直接与另一个数组相关。即....
tempCurrentOffsetArray[0]
是在 tempCurrentTimezoneArray[0]
处找到的时区的 UTC 偏移量。
此代码的其余部分旨在完成以下任务...
- 按 UTC 偏移量对时区和偏移量进行分组。
- 按字母顺序组织每个偏移量组。
- 创建两个数组,其中值首先按 UTC 偏移量组织,其次按字母顺序组织。
我遇到的问题是,在某些地区,我收到了几乎完美的列表,而在其他地区,我收到了一些带有看似随机数量的未定义值的列表,我不确定为什么。任何人都可以识别我的代码中的语法或逻辑错误吗?
tempCurrentTimezoneArray
输入数据的 JSON here
tempCurrentOffsetArray
输入数据的 JSON here
最佳答案
你想的还是太复杂了。保持这两个数组同步是一团糟,最好将一个数组与对象一起使用。
var region_selector = $("select[name='region_selector']").val();
var tempCurrentTimezoneArray = timezoneArray[ region_selector ];
var tempCurrentOffsetArray = timezoneOffsetArray[ region_selector ];
//consolidate the Arrays
var data = []; //create a new Array `data`
for(var i = tempCurrentOffsetArray.length; i--; ){
//write into Array `data` at index `i` an object, containing these properties:
//`timezone`, `offset` and `offsetValue`, and their respective values
data[i] = {
timezone: tempCurrentTimezoneArray[i],
offset: tempCurrentOffsetArray[i],
//the + at the beginning converts the value behind that into a Number, like parseFloat() would do
offsetValue: +tempCurrentOffsetArray[i].match(/^GMT([+-]\d+(?:\.\d+)?)$/)[1]
}
}
//sorter-function for data to sort the values by offsetValue ASC first, then by timezone ASC
function sortedByOffset(a, b){
return a.offsetValue - b.offsetValue || a.timezone.localeCompare(b.timezone);
}
//you should do this as late as possible, usually after the filtering
data.sort(sortedByOffset);
如果你坚持使用两个输出数组
var currentTimezoneArray = data.map(d => d.timezone);
var currentOffsetArray = data.map(d => d.offset);
否则这在我看来更灵活
//utilities to fetch a property off the object
var getTimezone = d => d.timezone;
//aka function getTimezone(d){ return d.timezone }
var getOffset = d => d.offset;
//aka function getOffset(d){ return d.offset }
//example usages:
data.filter(d => d.offset === "GMT-5").map( getTimezone );
data.filter(d => d.offsetValue >= -2 && d.offsetValue <= -5 ).map( getOffset );
以第一个例子为例;从 SQL 语句的 Angular 思考,这将是
SELECT timezone FROM data WHERE offset = "GMT-5"
获取偏移量为 GMT-5 的每个条目的时区值
您从包含所有值data
的数组开始,然后通过过滤获得您感兴趣的子集(在本例中为每个条目,偏移量为“GMT-5”)。
现在你有一个数组,其中包含你感兴趣的所有值,但仍然是整个对象;就像SELECT * FROM ...
map()
函数在此子集中的每个条目上调用函数getTimezone()
,并返回另一个仅包含时区值的数组。
第二个示例定义了过滤器的范围(从 GMT-2 到并包括 GMT-5 的每个条目以及其间的每个 GMT),并为这些条目返回 offset-property。
关于javascript - JavaScript中根据多值特征重新组织多维数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36514749/