Last active
May 30, 2019 06:48
-
-
Save Iainmon/9c0c8ab712417caffecd220a13da1e88 to your computer and use it in GitHub Desktop.
A decoder algorithm I wrote for parsing, and incrementing Chain of Custody asbestos sample numbers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// PatternDecoder.ts | |
export class PatternDecoder { | |
private prefix: string; | |
private splitter: string; | |
private startIndex: number | string; | |
private currentIndex: number | string; | |
constructor(prefix: string, suffix: number | string, splitter: string) { | |
this.prefix = prefix; | |
this.splitter = splitter; | |
this.startIndex = suffix; | |
this.currentIndex = suffix; | |
} | |
public next(): PatternDecoder { | |
let nextPatternDecoder: PatternDecoder; | |
// Casts the current index to a number or string, and increments up by one and instantiates a new patterndecoder object. | |
if (!isNaN(<number> this.currentIndex)) { | |
nextPatternDecoder = new PatternDecoder(this.prefix, <number>this.currentIndex + 1, this.splitter) ; | |
} else { | |
nextPatternDecoder = new PatternDecoder(this.prefix, String.fromCharCode((<string>this.currentIndex).charCodeAt(0) + 1), this.splitter); | |
} | |
// Returns the next, incremented, decoder object. | |
return nextPatternDecoder; | |
} | |
public previous(): PatternDecoder { | |
let previousPatternDecoder: PatternDecoder; | |
// Casts the current index to a number or string, and increments down by one and instantiates a new patterndecoder object. | |
if (!isNaN(<number> this.currentIndex)) { | |
previousPatternDecoder = new PatternDecoder(this.prefix, <number>this.currentIndex - 1, this.splitter) ; | |
} else { | |
previousPatternDecoder = new PatternDecoder(this.prefix, String.fromCharCode((<string>this.currentIndex).charCodeAt(0) - 1), this.splitter); | |
} | |
// Returns the previous, incremented, decoder object. | |
return previousPatternDecoder; | |
} | |
public getValue(): string { | |
// Returns the current string, based on the pattern. | |
return `${this.prefix}${this.splitter}${this.currentIndex}` | |
} | |
} | |
export function analyzePattern(pattern: string, splitAtLast: boolean = true): PatternDecoder | null { | |
// Acceptable splitters | |
let splitters = [ '-', '.' ]; | |
let splitter: string = null; | |
// Trys to find a splitter inside the string | |
for (let i = 0; i < splitters.length; i++) { | |
if (pattern.includes(splitters[i])) { | |
splitter = splitters[i]; | |
break; | |
} | |
} | |
// No acceptable splitter was found | |
if (splitter === null) { | |
return null; | |
} | |
// Finds how many times the splitter occurs in the string | |
let splitterOccurrences: number = pattern.split(splitter).length - 1; | |
if (splitterOccurrences > 1 && !splitAtLast) { | |
return null; | |
} | |
// Finds the prefix and the sufix of the pattern | |
let prefix = pattern.slice(0, pattern.lastIndexOf(splitter)); | |
let suffix = pattern.slice(pattern.lastIndexOf(splitter) + 1); | |
// Attempts to cast suffix to an integer | |
let integerCastAttempt = parseInt(suffix); | |
if (!isNaN(integerCastAttempt)) { | |
// Creates number pattern decoder | |
return new PatternDecoder(prefix, integerCastAttempt, splitter); | |
} else if (suffix.length == 1) { | |
// Creates character pattern decoder | |
return new PatternDecoder(prefix, suffix, splitter); | |
} else { | |
return null; // The suffix is not a number, and is an emptry string. | |
} | |
} | |
// PatternDecoderTest.ts | |
import { PatternDecoder, analyzePattern } from '../src/PatternDecoder'; | |
let basicPatternList = [ | |
'NUMERICSAMPLE-1', | |
'NUMERICSAMPLE.1', | |
'CHARACTERSAMPLE-a', | |
'NUMERICSAMPLE.a' | |
]; | |
let complexPatternList = [ | |
'NUMERIC-SAMPLE-1', | |
'NUMERIC.SAMPLE.1', | |
'CHARACTER-SAMPLE-a', | |
'NUMERIC.SAMPLE.a' | |
]; | |
for (let i = 0; i < basicPatternList.length; i++) { | |
let patternDecoder = analyzePattern(basicPatternList[i]); | |
if (patternDecoder === null) { | |
console.log('Could not find pattern for ' + basicPatternList[i]); | |
continue; | |
} | |
console.log(patternDecoder.previous().getValue()); | |
console.log(patternDecoder.getValue()); | |
console.log(patternDecoder.next().getValue()); | |
} | |
for (let i = 0; i < complexPatternList.length; i++) { | |
let patternDecoder = analyzePattern(complexPatternList[i]); | |
if (patternDecoder === null) { | |
console.log('Could not find pattern for ' + complexPatternList[i]); | |
continue; | |
} | |
console.log(patternDecoder.previous().getValue()); | |
console.log(patternDecoder.getValue()); | |
console.log(patternDecoder.next().getValue()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment