5
\$\begingroup\$

I am decoding GS1 barcodes and need to match up application identifiers with relevant data about them.

00 SSCC (Serial Shipping Container Code) N2+N18 FALSE SSCC 
01 Global Trade Item Number (GTIN) N2+N14 FALSE GTIN 
02 GTIN of Contained Trade Items N2+N14 FALSE CONTENT 
10 Batch or Lot Number N2+X.20 TRUE BATCH/LOT 
11 Production Date (YYMMDD) N2+N6 FALSE PROD DATE 
12 Due Date (YYMMDD) N2+N6 FALSE DUE DATE 
13 Packaging Date (YYMMDD) N2+N6 FALSE PACK DATE 
15 Best Before Date (YYMMDD) N2+N6 FALSE BEST BEFORE or BEST BY 
16 Sell By Date (YYMMDD) N2+N6 FALSE SELL BY 
17 Expiration Date (YYMMDD) N2+N6 FALSE USE BY OR EXPIRY 
20 Variant Number N2+N2 FALSE VARIANT 
21 Serial Number N2+X.20 TRUE SERIAL 
240 Additional Item Identification N3+X.30 TRUE ADDITIONAL ID 
241 Customer Part Number N3+X.30 TRUE CUST. PART NO. 
242 Made-to-Order Variation Number N3+N.6 TRUE MTO VARIANT 
243 Packaging Component Number N3+X.20 TRUE PCN 
250 Secondary Serial Number N3+X.30 TRUE SECONDARY SERIAL 
251 Reference to Source Entity N3+X.30 TRUE REF. TO SOURCE 
253 Global Document Type Identifier (GDTI) N3+N13+XTRUE GDTI 
254 GLN Extension Component N3+X.20 TRUE GLN EXTENSION COMPONENT 
255 Global Coupon Number (GCN) N3+N13+NTRUE GCN 
30 Count of Items (Variable Measu ... N2+N..8 TRUE VAR. COUNT 
3100 Net weight kilograms (Var... ) N4+N6 FALSE NET WEIGHT (kg) 
...

Full list here.

This is how I identify them:

public Dictionary<int, Tuple<string, string, bool, string>> gs1AiDict { get; private set; } 
var aiDataOut = new Tuple<string, string, bool, string>("","",false,"");
//Get first 4 digits (max identifier length)
//the string input pi might look like this: ~10000123
int applicationIdentifier = Convert.ToInt16(pi.Substring(1,4));
//Try to find an identifier with 2 digits.
if (gs1AiDict.TryGetValue(applicationIdentifier / 100, out aiDataOut))
{
 //assign found data to tuple
 id = aiDataOut.Item1;
 format = aiDataOut.Item2;
 func = aiDataOut.Item3;
 abrv = aiDataOut.Item4;
}
//look up the first 3 digits
else
{
 if (gs1AiDict.TryGetValue(applicationIdentifier / 10, out aiDataOut))
 {
 id = aiDataOut.Item1;
 format = aiDataOut.Item2;
 func = aiDataOut.Item3;
 abrv = aiDataOut.Item4;
 }
 //look up first 4 digits
 else
 {
 if (gs1AiDict.TryGetValue(applicationIdentifier, out aiDataOut))
 {
 id = aiDataOut.Item1;
 format = aiDataOut.Item2;
 func = aiDataOut.Item3;
 abrv = aiDataOut.Item4;
 }
 //no identifiers are 5 digits
 else
 {
 console.log("No Application Identifier found!");
 }
 }
}

My tests have worked wonderfully, but my issue is the readability and efficiency of this solution. Are 3 dictionary key look ups for about 140 keys too much?

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Nov 17, 2014 at 15:36
\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$

Code duplication is a sin

You could use shorter and more readable code using a simple for loop:

int applicationIdentifier = Convert.ToInt16(pi.Substring(1,4));
for (int i = 100; i >= 1; i /= 10)
{
 int maybeId = applicationIdentifier / i;
 if (gs1AiDict.TryGetValue(maybeId, out aiDataOut))
 {
 id = aiDataOut.Item1;
 format = aiDataOut.Item2;
 func = aiDataOut.Item3;
 abrv = aiDataOut.Item4;
 return;
 }
} 
Console.WriteLine("No Application Identifier found!");

You should also consider making your data object something along the lines of a Dicitionary<int, ApplicationInfo>, that 4-member tuple doesn't help readibility. Then you could also return an ApplicationInfo object instead of copying the fields to local variables.

answered Nov 17, 2014 at 16:01
\$\endgroup\$
2
  • \$\begingroup\$ Indeed that function is much cleaner. Regarding the use of "Application Info" to hold the data: could you point me to a use of that? When I was researching how to get multiple parameters per key, all I found were Tuples. \$\endgroup\$ Commented Nov 17, 2014 at 16:18
  • \$\begingroup\$ @Phyre ApplicationInfo is a name I made up, it's not a existing type. I was suggesting that you should create a class that holds a single entry of application information. \$\endgroup\$ Commented Nov 17, 2014 at 16:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.