我需要按照冰岛字母规则 (aábcdðeé....) 对字符串字段进行排序,因此我尝试将代码移植到 c# 并使用 StringComparer.InvariantCultureIgnoreCase 比较器。而且效果很好。
所以,这里是 Birbal Singh 代码的 c# 端口
CaseInsensitiveStringComparator.cs
public class CaseInsensitiveStringComparator : FieldComparerSource
{
public override FieldComparer NewComparer(string fieldname, int numHits, int sortPos, bool reversed)
{
return new CaseIgonreCompare(fieldname, numHits);
}
}
CaseIgonreCompare.cs
public class CaseIgonreCompare : FieldComparer<string>
{
private string _field;
private string[] _values;
private BinaryDocValues _cache;
private string _bottom;
private string _topValue;
public CaseIgonreCompare(string field, int numHits)
{
_field = field;
_values = new string[numHits];
}
public override IComparable this[int slot] => _values[slot];
public override int CompareValues(string first, string second)
{
int val = first.Length - second.Length;
return StringComparer.InvariantCultureIgnoreCase.Compare(first, second);
}
private string GetValue(int doc)
{
var bytesRef = new BytesRef();
_cache.Get(doc, bytesRef);
return bytesRef.Utf8ToString();
}
public override int Compare(int slot1, int slot2)
{
return string.Compare(_values[slot1], _values[slot2]);
}
public override int CompareBottom(int doc)
{
return CompareValues(_bottom, GetValue(doc));
}
public override int CompareTop(int doc)
{
return CompareValues(_topValue, GetValue(doc));
}
public override void Copy(int slot, int doc)
{
_values[slot] = GetValue(doc);
}
public override void SetBottom(int slot)
{
_bottom = _values[slot];
}
public override FieldComparer SetNextReader(AtomicReaderContext context)
{
_cache = FieldCache.DEFAULT.GetTerms(context.AtomicReader, _field, true);
return this;
}
public override void SetTopValue(object value)
{
_topValue = value as string;
}
}