// ---------------------------------------------------------------------- public static string[] SortAndTake_(string search, string[] lst, int maxNbOfResults = 0, float minScore = 0.5f) { // Define local sort function Action <P.Tuple <float, string>[]> sort = (ts) => { P.sort( ts, (t1, t2) => { var diff = t2.Item1 - t1.Item1; return(Math3D.IsZero(diff) ? 0 : (diff < 0 ? -1 : 1)); } ); }; // Correctly size result. var len = lst.Length; if (maxNbOfResults == 0) { maxNbOfResults = len; } if (maxNbOfResults > len) { maxNbOfResults = len; } var result = new P.Tuple <float, string> [maxNbOfResults]; int resultLen = 0; // Filter out the input list bool isSorted = false; foreach (var l in lst) { var score = GetScore(search, l); if (score <= minScore) { continue; } if (resultLen < maxNbOfResults) { result[resultLen] = P.curry(t => P.id(t), score, l); ++resultLen; if (resultLen == maxNbOfResults) { sort(result); isSorted = true; } } else { if (score > result[resultLen - 1].Item1) { result[resultLen - 1] = P.curry(t => P.id(t), score, l); sort(result); isSorted = true; } } // TODO: finish SortAndTake_ } // Perform a last sort in case we have not filled the max number of results. if (isSorted == false) { result = P.take(resultLen, result); sort(result); } return(P.map((t) => P.uncurry((score, str) => str, t), result)); }