JavaScript多维数组?

8

我希望我能用英语清楚地表达我想要创造的东西。我首先从我想要的开始。

我想制作一个IBAN计算器,可以生成1-n个IBAN号码,并验证给定的IBAN号码。IBAN号码在许多国家用于付款,我想制作的工具可以用于生成测试目的的号码。

wikipedia(荷兰网站)上,我找到了一个包含各个国家及其定义IBAN号码方式的列表。我想做的是创建一种数组,其中包含所有国家的名称、代码、IBAN长度、银行格式和账户格式。

该数组需要用于:

  1. 生成选择列表(用于选择国家)
  2. 用于生成号码的检查部分
  3. 用于验证号码的检查部分

我不知道数组是否是最好的方法,但那是我目前所拥有的最多的知识。

我已经制作了一张类似这样的表格来保存信息(这个表格并没有在任何地方使用,但对于我展示结构的想法来说是一个很好的方式):

<table>
 <tr>
  <td>countryname</td>
  <td>country code</td>
  <td>valid IBAN length</td>
  <td>Bank/Branch Code (check1, bank, branch)</td>
  <td>Account Number (check2, number, check3)</td>
 <tr>
 <tr>
  <td>Andorra</td>
  <td>AD</td>
  <td>24</td>
  <td>0  4n 4n</td>
  <td>0  12   0 </td>
 <tr>
 <tr>
  <td>België</td>
  <td>BE</td>
  <td>16</td>
  <td>0  3n 0 </td>
  <td>0   7n  2n</td>
 <tr>
 <tr>
  <td>Bosnië-Herzegovina</td>
  <td>BA</td>
  <td>20</td>
  <td>0  3n 3n</td>
  <td>0   8n  2n</td>
 <tr>
</table>

以及许多其他。

3个回答

40

主要答案

我不会使用"数组"来完成这个任务。JavaScript 对象是一种映射(有时称为“关联数组”,但我们使用“映射”以避免与按数字索引的数组混淆),因此您可以很容易地使用普通对象完成这个任务:

var IBANInfo = {
    "AD": {
        countryCode: "AD",
        countryName: "Andorra",
        length: 24,
        bankBranchCode: "0  4n 4n",
        accountNum: "0  12   0"
    },
    "BE": {
        countryCode: "BE",
        countryName: "Belgi\u00EB",
        length: 16,
        bankBranchCode: "0  3n 0",
        accountNum: "0  7n   2n"
    },
    "BA": {
        countryCode: "BA",
        countryName: "Bosni\u00EB-Herzegovina",
        length: 20,
        bankBranchCode: "0  3n 3n",
        accountNum: "0   8n  2n"
    }
};

(请注意,我已经使用带上缀符号的'e'的Unicode转义;这样做可能最好,但是如果您的编码正确,应该也没问题。)

代码使用对象字面量表示法创建单个对象和整个映射表。在整个映射表中,每个国家都有一个属性,属性键是国家代码,属性值是提供自己表格信息的对象。

然后,您可以像这样使用国家代码在映射表中查找国家的信息:

var countryInfo = IBANInfo["AD"]; // <= Example for Andorra

如果您有另一个变量中的国家代码:

var countryCode = "AD"; // <= Example for Andorra
var countryInfo = IBANInfo[countryCode];
alert("Country name: " + countryInfo.countryName); // <= Alerts "Country name: Andorra"

显然,如果你喜欢使用其他内容来查找,只需相应地进行调整。

在键上加前缀出于偏执

当我处理那些我几乎没有控制权的信息时,我通常会在键上添加前缀,以避免与对象的内置属性发生冲突(尽管我认为这里不太可能发生冲突)。例如,如果你使用了“cc”前缀,事情会变成这样:

该地图:

var IBANInfo = {
    "ccAD": {
        countryCode: "AD",
        countryName: "Andorra",
        length: 24,
        bankBranchCode: "0  4n 4n",
        accountNum: "0  12   0"
    },
    "ccBE": {
        countryCode: "BE",
        countryName: "Belgi\u00EB",
        length: 16,
        bankBranchCode: "0  3n 0",
        accountNum: "0  7n   2n"
    },
    "ccBA": {
        countryCode: "BA",
        countryName: "Bosni\u00EB-Herzegovina",
        length: 20,
        bankBranchCode: "0  3n 3n",
        accountNum: "0   8n  2n"
    }
};

查找:

var countryCode = "AD";                          // <= Example for Andorra
var countryInfo = IBANInfo["cc" + countryCode];  // <= Note we add the prefix on lookup
alert("Country name: " + countryInfo.countryName); // <= Alerts "Country name: Andorra"

遍历map中的键

如果你需要(出于任何原因)遍历所有键,由于它不是一个数组,你不能使用数字索引。幸运的是,这正是JavaScript中的for..in循环的用途:它遍历对象属性的名称(键):

var key;
for (key in IBANInfo) {
    if (IBANInfo.hasOwnProperty(key)) {
        // ...use key here, it'll be "ccAD" for Andorra, etc...
    }
 }
使用hasOwnProperty可以区分对象直接设置的属性和从其原型继承的属性。如果您不熟悉JavaScript的原型继承,请不要太担心,只需像上面的循环一样使用即可。

由于JavaScript数组是对象,而所有JavaScript对象都是映射,因此您甚至可以将数字索引和按国家/地区代码索引相结合。以下是一个示例:

地图:
// First, build the array
var IBANInfo = [
    {
        countryCode: "AD",
        countryName: "Andorra",
        length: 24,
        bankBranchCode: "0  4n 4n",
        accountNum: "0  12   0"
    },
    {
        countryCode: "BE",
        countryName: "Belgi\u00EB",
        length: 16,
        bankBranchCode: "0  3n 0",
        accountNum: "0  7n   2n"
    },
    {
        countryCode: "BA",
        countryName: "Bosni\u00EB-Herzegovina",
        length: 20,
        bankBranchCode: "0  3n 3n",
        accountNum: "0   8n  2n"
    }
];

// Now, cross-index it
var index, entry;
for (index = 0; index < IBANInfo.length; ++index)
{
    // Get the entry at this numeric index
    entry = IBANInfo[index];

    // Create the country code lookup for it
    IBANInfo["cc" + entry.countryCode] = entry;
}

这就是为什么前缀变得非常重要的原因,因为数组拥有比普通对象更多的属性。

按国家代码查找并没有改变:

var countryCode = "AD";
var countryInfo = IBANInfo["cc" + countryCode];    // <= Country code lookup
alert("Country name: " + countryInfo.countryName); // <= Alerts "Country name: Andorra"

但是如果您由于某种原因需要使用数字索引,现在也可以这样做:

var countryInfo = IBANInfo[0];                      // <= Numeric lookup
alert("Country name: " + countryInfo.countryName); // <= Also alerts "Country name: Andorra"
在事后进行交叉索引(如上所述)最适用于类似IBAN映射这样的静态内容。如果您将作为程序的一部分添加或删除条目,我可能会将其制作成可重复使用的对象。
如果我需要按数字和关键字查找,我通常会通过使映射方面成为数组属性而将事物稍微分离出来,而不是直接使用数组。这仅需要对创建映射的循环进行小更改,即在初始化数组后创建映射:
地图:
// First, build the array
var IBANInfo = [
    /* ...same as before, omitted for space... */
];

// Now, cross-index it
var index, entry;
IBANInfo.byCC = {}; // A new plain object to be our map
for (index = 0; index < IBANInfo.length; ++index)
{
    // Get the entry at this numeric index
    entry = IBANInfo[index];

    // Create the country code lookup for it
    IBANInfo.byCC["cc" + entry.countryCode] = entry;
}

国家代码查询,然后使用 byCC 属性:

var countryCode = "AD";
var countryInfo = IBANInfo.byCC["cc" + countryCode]; // <= Country code lookup
   // The change is here:-^^^^^
alert("Country name: " + countryInfo.countryName);  // <= Alerts "Country name: Andorra"

所以你有一堆选项:

  • 一个数组(通过数字索引查找,而不是通过国家代码; 这在其他答案中已有涉及,或者只需将交叉索引循环从上面删除)
  • 一个映射(通过国家代码查找,而不是通过数字索引)
  • 带有附加属性的数组(通过数字索引或国家代码查找)
  • 一个具有单独的byCC属性的数组,只是为了让我们都保持清醒

愉快的编码。


谢谢你的回答,这个“equal”/可以与JSON进行比较吗?我想我会使用JSON,但还是感谢你的回答和时间。问候。 - Megapool020
@megapool020:实际上这里的其他答案并没有使用JSON,尽管他们声称自己在使用。他们使用的是与我相同的对象字面量表示法。(JSON是对象字面量表示法的子集。)答案中的主要区别在于,其他人使用了数组(你只能通过数字索引访问条目),但我使用了映射(你可以通过它们的国家代码访问条目),这似乎更有用。如果你*只想通过数字索引查找东西,那么你可能需要使用一个数组。或者你甚至可以两者都做;我会添加一个两者的例子。 - T.J. Crowder
好的,谢谢,我会等你的例子。谢谢你在这上面花费了那么多时间和精力,我真的很感激。谢谢。我会离开几个小时,但今晚会检查它。 - Megapool020
嗨T.J,我能直接联系你吗?这样我就可以告诉你我用了什么。 - Megapool020
1
非常好的答案!它不仅回答了问题(如何处理他的情况),而且对其他人也非常有启发性。这个答案应该是“javascript多维数组”的#1谷歌搜索结果。 - David Hay
显示剩余4条评论

4

您可以像使用对象一样使用JavaScript...

为了方便起见,您可以使用JSON(纯JavaScript)

var ibans={countries:[
{"name": "Andorra",
"countryCode" : "ad",
mplahmpla:mplah},
{"name": "België",
"countryCode" : "ad",
mplahmpla:mplah},
{"name": "Other",
"countryCode" : "ad",
mplahmpla:mplah}
]
}

然后ibans.countries是一个包含所有国家的数组... ibans.countries[1].name将是Belgie 等等...

好的,这看起来是我可以使用的东西。我以前已经在JQUERY的插件中使用过JSON,但我认为我可以做更多的事情。感谢您的建议并向我解释它。还要感谢您的时间!问候 - Megapool020
说得严谨一点,那是对象字面量表示法,不是 JSON。(JSON 是对象字面量表示法的子集:http://json.org)如果前面没有 var ibans=,它就是其中之一。 :-) - T.J. Crowder

1
你可以使用一个带有关联数组的数组。
var variable = {
    "countries" : [
                    {"countryname" : "Andorra",
                     "country code" : "AD",
                     "valid IBAN length" : "24",
                     "Bank/Branch Code (check1, bank, branch)": "0  4n 4n",
                     "Acount Number (check2, number, check 3)": "0  12  0"
                    }, 
                    {"countryname" : "België",
                     "country code" : "BE",
                     "valid IBAN length" : "16",
                     "Bank/Branch Code (check1, bank, branch)": "0  3n 0 ",
                     "Acount Number (check2, number, check 3)": "0   7n  2n"    
                    }
                  ]
    };

你可能想查看JSON格式 http://www.json.org/

例如,variable(countries[0]["countryname"]); 将打印出 "安道尔"。


谢谢你的解决方案,我想我会使用JSON来完成它。 - Megapool020

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接