在javascript函数上排序数组

时间:2013-11-03 09:12:12

标签: javascript smarty

你好,我有这个聪明的代码,可以生成按国家ISO CODE排序的确定国家的州名单

countries = new Array();
{foreach from=$countries item='country'}
    {if isset($country.states)}
        countries[{$country.id_country|intval}] = new Array();
        {foreach from=$country.states item='state' name='states'}
            countries[{$country.id_country|intval}]['{$state.id_state|intval}'] = '{$state.name|escape:'htmlall':'UTF-8'}';
        {/foreach}
    {/if}
{/foreach}

Te restult就是这样,对我来说没问题,因为它是由ISO CODE订购的

countries = new Array();
countries[10] = new Array();
countries[10]['53'] = 'AG';
countries[10]['54'] = 'AL';
countries[10]['55'] = 'AN';
countries[10]['56'] = 'AO';
countries[10]['58'] = 'AP';
countries[10]['93'] = 'AQ';
countries[10]['57'] = 'AR';
countries[10]['59'] = 'AT';
countries[10]['60'] = 'AV';
countries[10]['61'] = 'BA';
countries[10]['64'] = 'BG';
countries[10]['65'] = 'BI';
countries[10]['62'] = 'BL';
countries[10]['63'] = 'BN';
countries[10]['66'] = 'BO';
countries[10]['69'] = 'BR';
countries[10]['68'] = 'BS';
countries[10]['162'] = 'BT';
countries[10]['67'] = 'BZ';
countries[10]['70'] = 'CA';
countries[10]['72'] = 'CB';
countries[10]['73'] = 'CE';
countries[10]['76'] = 'CH';
countries[10]['156'] = 'CI';
countries[10]['71'] = 'CL';
countries[10]['81'] = 'CN';
countries[10]['77'] = 'CO';
countries[10]['79'] = 'CR';
countries[10]['78'] = 'CS';
countries[10]['74'] = 'CT';
countries[10]['75'] = 'CZ';
countries[10]['82'] = 'EN';

在同一页面中我有这个javascript填充一个select html标签,但是按ID而不是ISO CODE订购选项标签,我不知道为什么

$(document).ready(function(){
    $('select#id_country').change(function(){
        updateState();
    });
    updateState();
});

function updateState()
{
    $('select#id_state option:not(:first-child)').remove();
        var states = countries[$('select#id_country').val()];
        if( typeof(states) != 'undefined' )
        {
            for (indexState in states)
            {
                //ie bug fix
                if (indexState != 'indexOf')
                    $('select#id_state').append('<option value="'+indexState+'"'+ (idSelectedCountry == indexState ? ' selected="selected' : '') + '">'+states[indexState]+'</option>');
            }
            $('p.id_state:hidden').slideDown('slow');
        }
        else
            $('p.id_state').slideUp('fast');
}

1 个答案:

答案 0 :(得分:0)

问题是ISO CODES的对象就像一个数组,而不是一个对象。当您将项目添加到具有数字索引的数组时,它将自动将其放入该数组中的特定顺序,这就是数组在javascript中的工作方式。
例如,如果您尝试使用此代码,则可以使用Chrome控制台:

var arr = [];
arr[4] = "data"; //same for arr['4'] - javascript will convert it to arr[4]
arr;

它会显示以下结果:

[undefined × 4, "data"]

这意味着它将创建所有5个索引(从0到4),前4个将是未定义的,第五个(索引4)将是您设置的值。
现在如果你要添加另一个低于4的索引,让我们说arr[2] = "Z Data";,现在数组将是:

[undefined × 2, "Z Data", undefined × 1, "data"]

如您所见,按自然数组的方式排序的值(无论内容和插入顺序如何)。

在您的情况下,如果您想要订购它,有几种方法可以完成它:
1 - 最好的选择是创建一个包含数据对象的有序数组:

var countries = new Array();
{foreach from=$countries item='country'}
    {if isset($country.states)}
        countries[{$country.id_country|intval}] = new Array();
        {foreach from=$country.states item='state' name='states'}
            countries[{$country.id_country|intval}].push({state_id: {$state.id_state|intval}, iso: '{$state.name|escape:'htmlall':'UTF-8'}'});
        {/foreach}
    {/if}
{/foreach}

将编译成:

var countries = new Array();
countries[10] = new Array();
countries[10].push({id: 53, iso:'AG'});
countries[10].push({id: 54, iso:'AL'});
countries[10].push({id: 55, iso:'AN'});
countries[10].push({id: 56, iso:'AO'});
countries[10].push({id: 58, iso:'AP'});
countries[10].push({id: 93, iso:'AQ'});
countries[10].push({id: 57, iso:'AR'});
countries[10].push({id: 59, iso:'AT'});
countries[10].push({id: 60, iso:'AV'});
//etc...

2 - 另一种选择是通过在数组索引前添加字符串来将数组转换为对象:

var countries = new Array();
{foreach from=$countries item='country'}
    {if isset($country.states)}
        countries[{$country.id_country|intval}] = {}; //object initialization
        {foreach from=$country.states item='state' name='states'}
            countries[{$country.id_country|intval}]['s{$state.id_state|intval}'] = '{$state.name|escape:'htmlall':'UTF-8'}';
        {/foreach}
    {/if}
{/foreach}

将编译成:

var countries = new Array();
countries[10] = {};
countries[10]['s53'] = 'AG';
countries[10]['s54'] = 'AL';
countries[10]['s55'] = 'AN';
countries[10]['s56'] = 'AO';
countries[10]['s58'] = 'AP';
countries[10]['s93'] = 'AQ';
countries[10]['s57'] = 'AR';
countries[10]['s59'] = 'AT';
countries[10]['s60'] = 'AV';
//ect...

将它用作对象后,它会按照您设置的顺序对列表进行排序。

3 - 此选项也是关于将数组转换为对象,但这次使用值切换索引:

var countries = new Array();
{foreach from=$countries item='country'}
    {if isset($country.states)}
        countries[{$country.id_country|intval}] = {}; //object initialization
        {foreach from=$country.states item='state' name='states'}
            countries[{$country.id_country|intval}]['{$state.name|escape:'htmlall':'UTF-8'}'] = {$state.id_state|intval};
        {/foreach}
    {/if}
{/foreach}

将编译成:

var countries = new Array();
countries[10] = {};
countries[10]['AG'] = 53;
countries[10]['AL'] = 54;
countries[10]['AN'] = 55;
countries[10]['AO'] = 56;
countries[10]['AP'] = 58;
countries[10]['AQ'] = 93;
countries[10]['AR'] = 57;
countries[10]['AT'] = 59;
countries[10]['AV'] = 60;
//ect...

4 - 最好的选择是将有序对象(如选项1中所述)编码为服务器端的JSON(PHP),并在客户端对其进行解码(JavaScript ),但需要更多时间来修复它。

希望它有所帮助,并且您了解JavaScript中数组的行为。

祝你好运!