using F23.StringSimilarity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Demo
{
/// <summary>
/// 相似度結(jié)果信息
/// </summary>
/// <typeparam name="TSource">源集合的類型</typeparam>
public class SimilarityResultInfo<TSource>
{
/// <summary>
/// 相似度值。值越小,表示差異越小。等于 1 表示只有一個(gè)字符差異。等于 0 表示完全相等。
/// </summary>
public double SimilarityValue { get; set; }
/// <summary>
/// 相似度等于 1 表示只有一個(gè)字符差異,則最接近的可能有一個(gè)或多個(gè)字符串
/// </summary>
public IEnumerable<TSource> SimilarityTargetList { get; set; }
}
/// <summary>
/// IEnumerable的擴(kuò)展類,擴(kuò)展了一個(gè)名為 Similarity 的方法
/// </summary>
public static class EnumerableMethodSimilarityExtension
{
/// <summary>
/// 獲取集合中和目標(biāo)字符串最相似的集合(備注:比如:相似度等于 1 表示只有一個(gè)字符差異,則最接近的可能有一個(gè)或多個(gè)字符串)
/// </summary>
/// <param name="source">源集合</param>
/// <param name="targetText">目標(biāo)字符串</param>
/// <returns>如果 source 沒有元素,則返回 NULL。否則,返回值不為 NULL</returns>
public static SimilarityResultInfo<string> Similarity(this IEnumerable<string> source, string targetText)
{
return Similarity<string>(source, c => c, targetText);
}
/// <summary>
/// 獲取集合中和目標(biāo)字符串最相似的集合(備注:比如:相似度等于 1 表示只有一個(gè)字符差異,則最接近的可能有一個(gè)或多個(gè)字符串)
/// </summary>
/// <typeparam name="TSource">源集合的類型</typeparam>
/// <param name="source">源集合</param>
/// <param name="textselector">源集合要比較的屬性</param>
/// <param name="targetText">目標(biāo)字符串</param>
/// <returns>如果 source 沒有元素,則返回 NULL。否則,返回值不為 NULL</returns>
public static SimilarityResultInfo<TSource> Similarity<TSource>(this IEnumerable<TSource> source, Func<TSource, string> textselector, string targetText)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (textselector == null)
{
throw new ArgumentNullException("textselector");
}
var l = new Levenshtein(); // 檢查 2 個(gè)字符串的相似度。
double? minStringSimilarityValue = null;
List<TSource> similarityTargetList = null;
foreach (var item in source)
{
string elementTextValue = textselector(item);
if (string.IsNullOrEmpty(elementTextValue))
{
continue;
}
double tempValue = l.Distance(elementTextValue, targetText);
if (!minStringSimilarityValue.HasValue)
{
//說(shuō)明是第一次比較。http://music.cnblogs.com
minStringSimilarityValue = tempValue;
similarityTargetList = new List<TSource>() { item };
continue;
}
if (tempValue < minStringSimilarityValue.Value)
{
minStringSimilarityValue = tempValue;
similarityTargetList.Clear();
similarityTargetList.Add(item);
continue;
}
if (tempValue == minStringSimilarityValue.Value)
{
similarityTargetList.Add(item);
continue;
}
}
if (!minStringSimilarityValue.HasValue)
{
//說(shuō)明集合是空的
return null;
}
SimilarityResultInfo<TSource> result = new SimilarityResultInfo<TSource>();
result.SimilarityValue = minStringSimilarityValue.Value;
result.SimilarityTargetList = similarityTargetList;
return result;
}
}
}