15

In php, one can handle a list of state names and their abbreviations with an associative array like this:

<?php
    $stateArray = array(
        "ALABAMA"=>"AL",
        "ALASKA"=>"AK",
        // etc...
        "WYOMING"=>"WY"
    );

    foreach ($stateArray as $stateName => $stateAbbreviation){
        print "The abbreviation for $stateName is $stateAbbreviation.\n\n";
    }
?>

Output (with key order preserved):

The abbreviation for ALABAMA is AL.

The abbreviation for ALASKA is AK.

The abbreviation for WYOMING is WY.

EDIT: Note that the order of array elements is preserved in the output of the php version. The Java implementation, using a HashMap, does not guarantee the order of elements. Nor does the dictionary in Python.

How is this done in java and python? I only find approaches that supply the value, given the key, like python's:

stateDict = {
    "ALASKA": "AK",
    "WYOMING": "WY",
}

for key in stateDict:
    value = stateDict[key]

EDIT: based on the answers, this was my solution in python,

# a list of two-tuples
stateList = [
    ('ALABAMA', 'AL'),
    ('ALASKA', 'AK'),
    ('WISCONSIN', 'WI'),
    ('WYOMING', 'WY'),
]

for name, abbreviation in stateList:
    print name, abbreviation

Output:

ALABAMA AL
ALASKA AK
WISCONSIN WI
WYOMING WY

Which is exactly what was required.

slang
  • 626
  • 7
  • 26
Lasoldo Solsifa
  • 375
  • 3
  • 5
  • 14
  • Why do you say that PHP's *"order of array elements is preserved in the output"*? Is this behavior **guaranteed** by the PHP docs? – Pacerier Apr 03 '15 at 18:35

8 Answers8

34

in Python:

for key, value in stateDict.items(): # .iteritems() in Python 2.x
    print "The abbreviation for %s is %s." % (key, value)

in Java:

Map<String,String> stateDict;

for (Map.Entry<String,String> e : stateDict.entrySet())
    System.out.println("The abbreviation for " + e.getKey() + " is " + e.getValue() + ".");
newacct
  • 119,665
  • 29
  • 163
  • 224
  • Thank you very much for your help. Regarding the Java version, I take for granted that May.Entry is simply misspelled. It can be really confusing for a novice sorting out code when it has even a small typo in it. Is it safe to assume that stateDict is in fact a Map? A HashMap? – Lasoldo Solsifa Aug 02 '09 at 19:20
  • thanx, fixed. stateDict is a Map – newacct Aug 02 '09 at 19:24
  • I have edited my question to underscore that the order of array elements is preserved in the output of the php version. The Java implementation, using a Map, does not appear to guarantee the order of elements. – Lasoldo Solsifa Aug 02 '09 at 19:44
  • 4
    use a `LinkedHashMap` if you need to keep the order of the elements. – cd1 Aug 02 '09 at 20:12
  • 1
    Thanks, CD1, for this suggestion. Meanwhile, the python version, using a dictionary, does not preserve order either. Any ideas? :) – Lasoldo Solsifa Aug 02 '09 at 20:18
  • 2
    Python dicts are, by definition, unordered. If you want ordered data in python, look at a list or other data structure. – nilamo Aug 02 '09 at 22:04
6

in java for associative array use Map

import java.util.*;

class Foo
{
    public static void main(String[] args)
    {
        Map<String, String> stateMap = new HashMap<String, String>();
        stateMap.put("ALABAMA", "AL");
        stateMap.put("ALASKA", "AK");
        // ...
        stateMap.put("WYOMING", "WY");

        for (Map.Entry<String, String> state : stateMap.entrySet()) {
             System.out.printf(
                "The abbreviation for %s is %s%n",
                state.getKey(),
                state.getValue()
            );
        }
    }
}
o948
  • 71
  • 1
  • 3
  • Thanks for the clear example! And it compiles and runs, does just what I expected. Your answer helped me sort out newacct's shorthand version. Frankly, without your code, I'd have been lost for quite a while. – Lasoldo Solsifa Aug 02 '09 at 19:25
  • Oops, noticed after the fact that the HashMap does not preserve order of elements. But a LinkedHashMap does! – Lasoldo Solsifa Aug 02 '09 at 20:36
2

Also, to maintain insertion order, you can use a LinkedHashMap instead of a HashMap.

  • Yep, a LinkedHashMap looks like exactly what I needed. Compiled, run, and the order is preserved. That's for the tip! – Lasoldo Solsifa Aug 02 '09 at 20:10
  • Your suggestion solved the Java version, can you recommend a replacement for the dictionary in acct's python version? It does not preserve order either... – Lasoldo Solsifa Aug 02 '09 at 20:19
2

In python an ordered dictionary is available in Python 2.7 (not yet released) and Python 3.1. It's called OrderedDict.

Alexander Ljungberg
  • 6,302
  • 4
  • 31
  • 37
  • Thanks for the tip! I was beginning to think my question might go unanswered. I will admit that I am distressed, though, if it is true that php’s foreach($array as $key => $value) cannot be implemented in python. I'm afraid I don't understand why a dictionary of ordered keys must lose its order when retrieved. It's perplexing. Now I suppose I'm on the lookout for a work-around. – Lasoldo Solsifa Aug 02 '09 at 21:01
  • @Lasoldo Solsifa: when you say "a dictionary of ordered keys" do you mean an OrderedDict instance or a normal Python dict? Because a normal Python dict NEVER has ordered keys -- the spec says that the keys may be returned in any order. The difference is PHP actually uses an associative array, and Python uses a hashtable. They are similar but not exactly the same. In Python <= 2.6, using a list of 2-tuples is probably the better solution. – Daniel Pryden Aug 02 '09 at 21:43
  • Not knowing python, I knew first of its forthcoming ordered dictionary from Alexander Ljungberg's response to my question. I'm only looking for an associative array in general, from which I may retrieve my keys in the order they were inserted. I will look into your suggestion of a list of 2-tuples. Thanks for the help. – Lasoldo Solsifa Aug 02 '09 at 21:53
  • The standard dictionary is not ordered for performance reasons I imagine. The most common way to use a dictionary is not to go over it item by item but to look up individual items when needed. If all you want is to display the dictionaries in alphabetical order you can use "for key, value in (key, stateDict[key] for key in sorted(stateDict.keys()):" – Alexander Ljungberg Aug 02 '09 at 22:13
2

This is the modified code from o948 where you use a TreeMap instead of a HashMap. The Tree map will preserve the ordering of the keys by the key.

import java.util.*;

class Foo
{
 public static void main(String[] args)
 {
    Map<String, String> stateMap = new TreeMap<String, String>();
    stateMap.put("ALABAMA", "AL");
    stateMap.put("ALASKA", "AK");
    // ...
    stateMap.put("WYOMING", "WY");

    for (Map.Entry<String, String> state : stateMap.entrySet()) {
             System.out.printf(
                    "The abbreviation for %s is %s%n",
                    state.getKey(),
                    state.getValue()
            );
      }
    }
 }
Milhous
  • 14,473
  • 16
  • 63
  • 82
  • 1
    Thanks for the help. Answers to my question also indicated that a LinkedHashMap would preserve element order, so I did like you, only I substituted LinkedHashMap for the HashMap. Yours works too, so now I can choose between two solutions! – Lasoldo Solsifa Aug 02 '09 at 21:03
  • Oops. Pilgrim points out that TreeMap sorts elements by key, while LinkedHashMap preserves original order, which is what was required. – Lasoldo Solsifa Aug 03 '09 at 11:07
1

Another way of doing it in Java. Although a better way has already been posted, this one's syntactically closer to your php code.

for (String x:stateDict.keySet()){
        System.out.printf("The abbreviation for %s is %s\n",x,stateDict.get(x));
    }
MAK
  • 26,140
  • 11
  • 55
  • 86
1

Along the lines of Alexander's answer...

The native python dictionary doesn't maintain ordering for maximum efficiency of its primary use: an unordered mapping of keys to values.

I can think of two workarounds:

  1. look at the source code of OrderedDict and include it in your own program.

  2. make a list that holds the keys in order:

    states = ['Alabamba', 'Alaska', ...]  
    statesd = {'Alabamba':'AL', 'Alaska':'AK', ...}
    for k in states:
        print "The abbreviation for %s is %s." % (k, statesd[k])
    
A B
  • 8,340
  • 2
  • 31
  • 35
  • Daniel Pryden's suggestion of a list of two-tuples may be better. e.g. [('Alabamba', 'AL'), ('Alaska', 'AK'), ...] – A B Aug 02 '09 at 22:01
0

TreeMap is not an answer to your question because it sorts elements by key, while LinkedHashMap preserves original order. However, TreeMap is more suitable for the dictionary because of sorting.

Denis Tulskiy
  • 19,012
  • 6
  • 50
  • 68
  • Thank you so much for pointing this out. Since my list of US states is, for the most part, in alphabetical order, I didn't notice that TreeMap was actually sorting the elements! I tested it, and sure enough, it did not preserve insertion order. Unlike LinkedHashMap, which remains the winner in this case. – Lasoldo Solsifa Aug 03 '09 at 11:00