Skip to content

Instantly share code, notes, and snippets.

@bobbysmith007
Last active February 17, 2017 18:31
Show Gist options
  • Save bobbysmith007/0cc83eec1a1f48010f1671ebb0729984 to your computer and use it in GitHub Desktop.
Save bobbysmith007/0cc83eec1a1f48010f1671ebb0729984 to your computer and use it in GitHub Desktop.
How creating nested hash tables explicitly/imperitively was much simpler than LINQ expressions
// This is the code that replaced all the code below this function:
protected override IDictionary<int, Dictionary<string, string>> GroupAndFlatten(IEnumerable<PassengerImport> imports) {
var paxImports = imports.GroupBy(x => x.PassengerId);
var paxes = new Dictionary<int,Dictionary<string,string>>();
foreach(var row in imports){
var paxid = row.PassengerId;
if (!paxes.ContainsKey(paxid)) paxes[paxid] = new Dictionary<string,string>();
var paxHash = paxes[paxid];
if(paxHash.ContainsKey(row.Key)) paxHash[row.Key] += " "+ row.Value;
else paxHash[row.Key] = row.Value;
}
return paxes;
}
protected override IEnumerable<IDictionary<string, object>> Convert(IEnumerable<PassengerImport> imports) {
// resolve any laziness, we need to loop over this multiple times
foreach(var paxHash in GroupAndFlatten(imports)){
var o =new Dictionary<string, object>(){
{"PaxId", paxHash.Key},
{"SpecialNeed", paxHash.Value.Get("PROG_NUM","")+" "+paxHash.Value.Get("PROG_NAME","")}
};
yield return o;
}
}
}
// This is the code I couldnt understand
object MergeFields(IGrouping<string, object> x) {
// don't want to merge this key
if (x.Key == this.PassengerIdParamName) {
return x.First();
}
return (object) string.Join(" ", x);
}
IDictionary<string, object> CombineRows(ICollection<PassengerImport> imps, IDictionary<int, List<int?>> importLines) {
return importLines
// convert to paxId / lineNumber pairs
.SelectMany(x => x.Value.Select(y => new { pId = x.Key, ln = y }))
// `IEnumerable<PassengerImport>`s for each paxId / lineNumber
.Select(x => imps.Where(y => y.PassengerId == x.pId &&
y.LineNumber == x.ln))
// convert those to lists of SQL params for SP calls
.Select(base.Convert)
// expect only one param set
.Select(x => x.Single())
// get a list of all key/value pairs
.SelectMany(x => x)
// group by key
.GroupBy(x => x.Key, x => x.Value)
// join values
.ToDictionary(x => x.Key, MergeFields);
}
protected override IEnumerable<IDictionary<string, object>> Convert(IEnumerable<PassengerImport> imports) {
// resolve any laziness, we need to loop over this multiple times
var imps = imports.ToList();
// get a dict mappping: paxId -> list of unique line numbers
var importLines = imps
.GroupBy(x => x.PassengerId)
.ToDictionary(x => x.Key, x => x.Select(y => y.LineNumber).Distinct().ToList());
var hasMultipleSpecNeeds = importLines.Any(x => x.Value.Count > 1);
if (hasMultipleSpecNeeds) {
return new[] { CombineRows(imps, importLines) };
} else {
return base.Convert(imports);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment