public static TagMatches GetTagMatchesRight(IList<string> inputTagStringList, IList<string> acceptedTagList, TagMatchMode mode) { IList<IList<string>> haystackTagList = GetSortedTagList(acceptedTagList); List<string> needleTagList = inputTagStringList.ToList(); bool noSkipping = (TagMatchMode.REQUIRE_FIRST_MATCH & mode) == TagMatchMode.REQUIRE_FIRST_MATCH; bool sequentialOnly = (TagMatchMode.SUCCESSIVE & mode) == TagMatchMode.SUCCESSIVE; TagMatch match; TagMatches matches = new TagMatches(); // TODO: This function (and original) seriously needs some sanity checks. // Actually maybe not... i was thinking about noSkipping and match.length == 0 below - but gettagmatch with !noSkipping would search the entire input list - IT handles the skipping while (needleTagList.Count > 0) { match = GetTagMatchRight(needleTagList, haystackTagList, mode); if (match.Length <= 0) { // We didn't get a match. // if noSkipping : Terminate! We require all tags to match! // if !noSkipping : Terminate! We're allowed to skip tags, and yet we didn't get a match - that means we must've gone through to the end. // All that's left to do is add tag string list to unmatched tags and return matches. break; } else if (match.Length > 0) { // got match // We got a match, but it wasnt the first tag (this MUST mean noSkipping is False) if (match.Index + match.Length < needleTagList.Count - 1 && sequentialOnly && matches.Count > 0) { // match was not first tag. This is a problem if sequentialOnly == true, UNLESS this is the first match! // Lets take sequential matches we got and go home merrily. break; } needleTagList.RemoveRange(match.Index + match.Length, needleTagList.Count - (match.Index + match.Length)); // We got a match. It's Index may be greater than 0, however in the block above ALL unmatched tags BEFORE the match were removed. // So effectively, the matched tag is at Index == 0. // add the matched tag to Matches. matches.Matches.Add(match); // remove the tags we just matched from the tag list // again: index is 0 because all preceeding unmatched tags were removed needleTagList.RemoveRange(match.Index, match.Length); // remove the matched tag too! This way it will never be matched again! haystackTagList.RemoveAt(match.MatchIndex); } } // add a string for the remaining tags we havent matched. //if (needleTagList.Count > 0) // matches.UnmatchedTagSequences.Add(TagListToString(needleTagList)); matches.Matches = matches.Matches.Reverse().ToList(); return matches; }
/// <summary> /// /// </summary> /// <param name="inputTagStringList"></param> /// <param name="acceptedTagList"></param> /// <param name="sequentialOnly"></param> /// <param name="noSkipping"></param> /// <returns></returns> public static TagMatches GetTagMatches(IList<string> inputTagStringList, IList<string> acceptedTagList, bool sequentialOnly, bool noSkipping) { IList<IList<string>> haystackTagList = GetSortedTagList(acceptedTagList); List<string> needleTagList = inputTagStringList.ToList(); TagMatch match; TagMatches matches = new TagMatches(); while (needleTagList.Count > 0) { match = GetTagMatch(needleTagList, haystackTagList, !noSkipping); if (match.Length == 0) { // We didn't get a match. // if noSkipping : Terminate! We require all tags to match! // if !noSkipping : Terminate! We're allowed to skip tags, and yet we didn't get a match - that means we must've gone through to the end. // All that's left to do is add tag string list to unmatched tags and return matches. break; } else if (match.Length > 0) { // We got a match, but it wasnt the first tag (this must mean noSkipping is False) if (match.Index > 0 && sequentialOnly && matches.Count > 0) { // match was not first tag. This is a problem if sequentialOnly == true, UNLESS this is the first match! break; } if (match.Index > 0) { // copy all tags from start until just before the matching tag List<string> tempUnmatched = needleTagList.GetRange(0, match.Index); // remove all tags before the match needleTagList.RemoveRange(0, match.Index); // append the unmatched tags we just got to the unmatched tags list. // Add all unmatched tags we go before this match to Matches.UnmatchedTagSequences matches.UnmatchedTagSequences.Add(TagListToString(tempUnmatched)); // Remove all items from the local Unmatched list. // this is in order to keep tag "clusters" intact. Unmatched tags must be added in batches like this. } // We got a match. It's Index may be greater than 0, however in the block above ALL unmatched tags BEFORE the match were removed. // So effectively, the matched tag is at Index == 0. // add the matched tag to Matches. matches.Matches.Add(match); // remove the tags we just matched from the tag list // again: index is 0 because all preceeding unmatched tags were removed needleTagList.RemoveRange(0, match.Length); } } // add a string for the remaining tags we havent matched. if (needleTagList.Count > 0) matches.UnmatchedTagSequences.Add(TagListToString(needleTagList)); return matches; }