/// <summary> /// Merges multiple ResultObjects of different categories to a single list of ContentObjects. /// The merge is based on a set of weights. /// </summary> /// <param name="results">An array of different ResultObjects for several categories</param> /// <param name="ratio">An array with weights for the different categories in the results array</param> /// <returns> /// A list of ContentObjects where the content's value is the weighted score per category. The list is sorted in /// descending order (the higher the value, the earlier in the list) /// </returns> public List <ContentObject> Merge(ResultObject[] results, CategoryRatio ratio) { // Attetion! No sanity checks: Must be different result.categories, ratios must sum up to 1. var totalResults = new List <ContentObject>(); var scores = Prepare(results); while (scores.Count > 0) { var list = Pop(scores); while (list.Count > 0) { var needle = Pop(list); var lonely = true; foreach (var haystack in scores) { var size = haystack.Count; for (var i = 0; i < size; i++) { if (needle.Equals(haystack[i])) { var t = haystack[i]; totalResults.Add(MergeWeighted(needle.Key, new[] { needle.Score, t.Score }, new[] { ratio.GetRatio(needle.Category), ratio.GetRatio(t.Category) })); haystack.Remove(t); size--; lonely = false; } } } if (lonely) { var weightedScore = needle.Score * ratio.GetRatio(needle.Category); totalResults.Add(new ContentObject(needle.Key, weightedScore.ToString())); } } } totalResults.Sort((a, b) => - 1 * a.CompareTo(b)); return(totalResults); }