Finding a way to smooth a separator string in a StringDictionary

I created the following to expose some data as a regular expression matching string, as well as StringDictionary. It looks like I could do this using LINQ with fewer rows.

private const string STREETTYPES = @"ALY|Alley|AVE|Avenue|BLVD|Boulevard|CIR|Circle|CT|Court|CTR|Center|DR|Drive|EXPY|Expressway|FWY|Freeway|HALL|Hall|HWY|Highway|JCT|Junction|LN|Lane|LP|Loop|PIKE|Pike|PKWY|Parkway|PL|Place|RD|Road|ST|Street|TER|Terrace|TPKE|Turnpike|TRL|Trail|WAY|Way";

  private static StringDictionary streetTypes = null;
  public static StringDictionary StreetTypes
  {
    get
    {
      if (streetTypes != null) return streetTypes;
      streetTypes = new StringDictionary();
      var streetArray = STREETTYPES.Split(PIPE);
      for (int i = 0; i < streetArray.Length-1; i = i+2)
      {
        streetTypes.Add(streetArray[i], streetArray[i + 1]);
      }
      return streetTypes;
    }
  }
+5
source share
5 answers

How about just:

private static readonly StringDictionary streetTypes = new StringDictionary
{
    {"ALY","Alley"},{"AVE","Avenue"},{"ALY","Alley"},{"BLVD","Boulevard"},{"CIR","Circle"},
    {"CT","Court"},{"CTR","Center"},{"DR","Drive"},{"EXPY","Expressway"},{"FWY","Freeway"},
    {"HALL","Hall"},{"HWY","Highway"},{"JCT","Junction"},{"LN","Lane"},{"LP","Loop"},
    ...        
};
+4
source

It's good?

var x = STREETTYPES.Split(new[] {'|'});
var output = Enumerable
    .Range(0, x.Length / 2)
    .ToDictionary(s => x[2 * s], s => x[2 * s + 1]);

Perhaps it can be squeezed further, but today I was sleeping half asleep.

+1
source

Linq, - , :

var input = STREETTYPES.Split('|');
var dict = input.Select( (x,i) => new { Item = x, Index = i })
                .Where(x => x.Index % 2 == 0)
                .ToDictionary( x=> input[x.Index], x => input[x.Index + 1]);
+1

dict- Python:

IDictionary<TKey, TVal> 
ToDictionary<TKey, TVal>(IEnumerable<TKey> keys, 
                         IEnumerable<TVal> values) 
{
    return keys.Zip(values, (k, v)=>new {K=k, V=v}).ToDictionary(kv=>kv.K, kv=>kv.V);
}

var str = @"ALY|Alley|AVE|Avenue|BLVD|Boulevard|CIR|Circle|CT|Court|CTR|Center|DR|Drive|EXPY|Expressway|FWY|Freeway|HALL|Hall|HWY|Highway|JCT|Junction|LN|Lane|LP|Loop|PIKE|Pike|PKWY|Parkway|PL|Place|RD|Road|ST|Street|TER|Terrace|TPKE|Turnpike|TRL|Trail|WAY|Way";
var words = str.Split('|');
var keys = words.Where((w, i) => i%2 == 0);
var values = words.Where((w, i) => i%2 != 0);
var dict = ToDictionary(keys, values);

Dictionary<string, string>, StringDictionary. , oneliner.

(Now I want C # to have less elementary support for ad-hoc data structures, I skip assignments for destructuring.)

An alternative version that does not require Zip () and thus will work with older versions of .NET, and avoids highlighting a list of temporary key / value pairs:

IDictionary<TKey, TVal> 
ToDictionary<TKey, TVal>(IEnumerable<TKey> keys, 
                         IEnumerable<TVal> values) 
{
    return Enumerable.Range(0, keys.Count()).ToDictionary(i=>keys.ElementAt(i), i=>values.ElementAt(i));
}
0
source

This will give you StringDictionarywhat you are looking for without doing positional math. If you can use Dictionary, I would go with it and one of the other published solutions.

var types = new StringDictionary();
using (IEnumerator<string> enumerator = streetTypes.Split('|').AsEnumerable().GetEnumerator())
{
    while(enumerator.MoveNext())
    {
        string first = enumerator.Current;
        if (!enumerator.MoveNext()) 
            break;
        types.Add(first, enumerator.Current);
    }
}
0
source

All Articles