views:

242

answers:

3

Hi there,

I hope I can make myself clear in English and in what I want to create. I first start with what I want.

I want to make a IBANcalculator that can generate 1-n IBANnumbers and also validate a given IBANnumber. IBANnumbers are used in many countries for payment and the tool I want to make can be used to generate the numbers for testing purpose.

On wikipedia (Dutch site) I found a list with countries and their way of defining the IBANnumber. What I want to do it to make a kind of an array that holds all the countries with their name, the code, there IBANlength, the bankingformat and the account format.

The array needs to be used to:

  1. Generate a select list (for selecting a country)
  2. used to check part for generating numbers
  3. used to check part for validating number

I don't know if an array is the best way, but that's so far the most knowledge I have.

I allready made a table like this that holds the info (this table isn't used anyware, but it was a good way for me to show you what I have in mind about how the structure is):

<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>

and many more ;-)

I hope someone can help me with this. Tnx in advance

+3  A: 

You can use javascript like objects...

For easyness you can use JSON (plain javascript)

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

then ibans.countries is an array with all countries... ibans.countries[1].name will be Belgie etc...

Parhs
Ok, this looks like something I can use. I already used JSON before, but only in a plyugin for JQUERY. But I think I can do more with this. Tnx for the sugestion and explaining it to me. Also tnx for your time!Grtzz
Megapool020
Being *pedantic*, that's object literal notation, not JSON. (JSON is a subset of object literal notation: http://json.org) Without the `var ibans=` at the front, it would be either. :-)
T.J. Crowder
A: 

You could use an array with associative arrays.

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"    
                    }
                  ]
    };

You might want to check out JSON format http://www.json.org/.

For example, variable(countries[0]["countryname"]); prints out "Andorra".

TK
Tnx for you solution, I think I'm going to use JSON to do the with
Megapool020
+4  A: 

The main answer

I wouldn't use an "array" for this at all. JavaScript objects are maps (sometimes called "associative arrays," but let's use "map" to avoid confusion with numerically-indexed arrays), so you can do this with plain objects quite easily:

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"
    }
};

(Note that I've used the Unicode escape for the 'e' with the umlaut above it; probably for the best, although if you're careful with your encodings you should be fine.)

That uses object literal notation to create the individual objects and the overall map. In the overall map, there is a property for each country, with the property key being the country code and the property value being an object providing the information from your table.

You can then look up a country's information in the map using its country code like this:

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

Or if you have the country code in another variable:

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

Obviously if you prefer to look up by something other than country code, just adjust things accordingly.

Putting a prefix on keys out of paranoia

When doing this with information I have little control over, I usually put a prefix on the key to avoid running into issues with conflicts with the built-in properties of an object (although I don't think there's much likelihood of conflict here). If you used a "cc" prefix, for instance, things would look like this:

The map:

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"
    }
};

The lookup:

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"

Looping through the keys in the map

If you need (for any reason) to loop through all of these, since it's not an array you can't use a numeric index. Fortunately, this is exactly what the JavaScript for..in loop is for: It looks through the names (keys) of the object's properties:

var key;
for (key in IBANInfo) {
    if (IBANInfo.hasOwnProperty(key)) {
        // ...use key here, it'll be "ccAD" for Andorra, etc...
    }
 }

(You use hasOwnProperty to differentiate between properties the object has set on it directly vs. those it gets from its prototype. If you're not familiar with JavaScript's prototypical inheritance, don't worry too much, just be sure to use a loop like the above.)

Best of both worlds

Since JavaScript arrays are objects, and all JavaScript objects are maps, you can even combine numeric indexing and indexing by country code. Here's an example of that:

The map:

// 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;
}

This is where those prefixes become very important, because arrays have more properties than plain objects.

The lookup by country code is unchanged:

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

But now if (for some reason) you need to use a numeric index, you can also do that:

var countryInfo = IBANInfo[0];                      // <= Numeric lookup
alert("Country name: " + countryInfo.countryName); // <= Also alerts "Country name: Andorra"

Cross-indexing after the fact as aboev is best only for static things like your IBAN map. If you were going to be adding or removing entries from this as part of your program, I'd probably make a reusable object out of it instead.

If I need things both numerically and by a key, I usually separate things out a bit by making the map aspects a property of the array rather than using the array directly. That requires only a small change to our loop that creates the map after we've initialized the array:

The map:

// 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;
}

Country code lookups then use the byCC property:

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"

So there you are, a bunch of options:

  • An array (look up by numeric index, not by country code; this is covered by other answers, or just leave the cross-indexing loop off the above)
  • A map (look up by country code, not by numeric index)
  • An array with additional properties (look up via numeric index or country code)
  • An array with a separate byCC property on it, just to keep us all sane

Happy coding.

T.J. Crowder
Tnx for your answer, it this "equal"/can be compared to JSON? I think I'm going to use JSON, but tnx for your answer and your time. Grtzz
Megapool020
@megapool020: Actually the other answers here aren't using JSON, even though they say they are. They're using the same thing I am, object literal notation. (JSON is a subset of object literal notation.) The main difference in the answers is that the others are using an array (you only get at entries via numeric index), but I'm using a map (you get at entries via their country code), which seemed more likely to be useful. If you *only* want to look things up by numeric indexes, you may want to use an array instead. Or you can even do both; I'll add an example of both.
T.J. Crowder
OK, tnx I'll wait for your example. Tnx you put so much time and effort in this.I really appriciate it.Tnx. Be away for a few hours, but will check it tonight.
Megapool020
Hi T.J, Is there a way that I can contact you directly, so that I can let you know what I've used.
Megapool020
@megapool020: If you like, though it's usually better to keep things on the site so that lurkers and future searchers can benefit. But my email address isn't remotely secret, so posting it here isn't going to suddenly increase my spam load: tj / crowdersoftware / com
T.J. Crowder
Ok, TJ, I have 2 questions: 1. first you use var "IBANInfo = {", later you use var "IBANInfo = [", first works, second not2. In the cross-index the IBANInfo.length gives undefined. I use JQUERY, does that give the problem?
Megapool020
@megapool020: 1. Was a copy I've fixed it. 2. May be a side-effect of the same problem; I'm not seeing a separate problem. jQuery won't have an effect on the above code either way. In your private note you said you only needed numeric indexes, not keyed lookup (country code and the like). If so, you want to ditch the cross index entirely, just use the straight array (`var IBANInfo = [...];`) version, which is pretty much the same in all of the answers here. (I assumed you would want/need keyed lookup for efficient location of the country info.) Enjoy!
T.J. Crowder
Hi T.J, tnx for the answer. I got it working now. Tnx very much
Megapool020