public static IEnumerable <TResult> SelectMany <TSource, TResult>(this IZippable <TSource> source, Func <TSource, IZippable <TResult> > selector) { if (source == null) { throw new ArgumentNullException("source"); } if (selector == null) { throw new ArgumentNullException("selector"); } return(SelectManyImpl(source, (value, index) => selector(value), (originalElement, subsequenceElement) => subsequenceElement)); }
public static void Unzip(IEnumerable <string> paths, IEnumerable <string> selectors, string location) { foreach (string path in paths) { ZipDirectory rootDir = Index(path); if (rootDir == null) { continue; } using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(path, FileMode.Open)) { foreach (string selector in selectors) { ConsoleUtil.PrintInfo($"Searching for selector: {selector}"); IZippable zip = SelectorSearch( rootDir, selector.Split( new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries)); try { if (zip is ZipDirectory zdir) { ConsoleUtil.PrintMessage( $"Unpacking directory {zdir.Name} from {path}"); UnpackDirectory(zdir, mmf, location); } else if (zip is ZipFile zfile) { ConsoleUtil.PrintMessage( $"Unpacking file {zfile.Name} from {path}"); UnpackFile(zfile, mmf, location); } else { ConsoleUtil.PrintWarning( $"Selector {selector} not found in {path}"); } } catch (CorruptionException) { ConsoleUtil.PrintError( "Unable to unzip because the .czip file is corrupt"); } } } } }
private static IZippable SelectorSearch(ZipDirectory root, IEnumerable <string> selector) { if (selector.Count() == 0) { return(root); } ConsoleUtil.PrintInfo($"Searching for {selector.First()} in {root.Name}"); IZippable zip = root.FindByName(selector.First()); if (selector.Count() == 1) { return(zip); } if (zip is ZipDirectory zdir) { return(SelectorSearch(zdir, selector.Skip(1))); } return(null); }
/// <summary> /// Actual code for SelectMany implementation. Instead of doing Cartesian Product, it /// performs zipping. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TCollection"></typeparam> /// <typeparam name="TResult"></typeparam> /// <param name="source"></param> /// <param name="collectionSelector"></param> /// <param name="resultSelector"></param> /// <returns></returns> private static IEnumerable <TResult> SelectManyImpl <TSource, TCollection, TResult>(IZippable <TSource> source, Func <TSource, int, IZippable <TCollection> > collectionSelector, Func <TSource, TCollection, TResult> resultSelector) { int index = 0; using (var e1 = source.GetEnumerator()) { // a default(TSource) causes that using nested "from" in LINQ won't work. Example of what's not allowed: // from entity in entities // from element in entity.collection <- this won't work // .... using (var e2 = collectionSelector(default(TSource), index++).GetEnumerator()) { while (true) { var isNext1 = e1.MoveNext(); var isNext2 = e2.MoveNext(); if (isNext1 && isNext2) { yield return(resultSelector(e1.Current, e2.Current)); } else { yield break; } } } } }
public static IEnumerable <TResult> SelectMany <TSource, TCollection, TResult>(this IZippable <TSource> source, Func <TSource, IZippable <TCollection> > selector, Func <TSource, TCollection, TResult> select) { return(SelectManyImpl(source, (value, index) => selector(value), select)); }