protected virtual bool TryGetFilteredFullKeys(int position, T subKey, ISet <K> source, out HashSet <K> target) { if (source.Count == 0) { target = default(HashSet <K>); return(false); } target = new HashSet <K>(EqualityComparerExtensions.ReferenceEqualityComparerOf <K>()); foreach (K fullKey in source) { if (SubKeyComparer.Equals(subKey, fullKey.ElementAtOrDefault(position))) { target.Add(fullKey); } } if (target.Count == 0) { target = default(HashSet <K>); return(false); } return(true); }
public override bool TryGetFullKeysByPartialKey(IEnumerable <T> subKeys, IEnumerable <int> positions, out IEnumerable <K> fullKeys) { if (subKeys == null) { throw new ArgumentNullException("subKeys"); } if (positions == null) { throw new ArgumentNullException("positions"); } if (!subKeys.Any()) { fullKeys = default(IEnumerable <K>); return(false); } IList <int> positionList = positions as IList <int> ?? positions.ToList(); IList <T> subKeyList = subKeys as IList <T> ?? subKeys.ToList(); IList <ISet <K> > subResults = new List <ISet <K> >(); int minSize = int.MaxValue; int minPos = -1; foreach (var subKey in subKeyList) { if (!partMap.TryGetValue(subKey, out ISet <K> subResult)) { fullKeys = default(IEnumerable <K>); return(false); } if (subResult.Count < minSize) { minSize = subResult.Count; minPos = subResults.Count; } subResults.Add(subResult); } if (subResults.Count == 0) { fullKeys = default(IEnumerable <K>); return(false); } HashSet <K> result; if (GetAtOrNegative(positionList, minPos) < 0) { result = new HashSet <K>(subResults[minPos], EqualityComparerExtensions.ReferenceEqualityComparerOf <K>()); } else if (!TryGetFilteredFullKeys(GetAtOrNegative(positionList, minPos), subKeyList[minPos], subResults[minPos], out result)) { fullKeys = default(IEnumerable <K>); return(false); } if (subResults.Count == 1) { fullKeys = result; return(true); } for (int i = 0; i < subResults.Count; i++) { if (i != minPos) { result.IntersectWith(subResults[i]); if (result.Count == 0) { fullKeys = default(ISet <K>); return(false); } } } var subKeyPosList = subKeyList .Zip <T, int, (T subKey, int position)>(positionList, (subKey, position) => (subKey, position)) .Where((tuple, index) => (index != minPos) && (tuple.position > 0)) .ToList(); if (subKeyPosList.Count != 0) { // could be streamed via IEnumerable result.Where(<the predicate opposite the one below>) but then subKeyList and positionList should always be copied result.RemoveWhere(key => { foreach (var subKeyPos in subKeyPosList) { if (!SubKeyComparer.Equals(subKeyPos.subKey, key.ElementAtOrDefault(subKeyPos.position))) { return(true); } } return(false); }); if (result.Count == 0) { fullKeys = default(IEnumerable <K>); return(false); } } fullKeys = result; return(true); }