添加Item后,我必须快速对ListCollectionView中的项进行排序。 我尝试使用CustomSort并创建自己的IComparer
ListCollectionView中的项目是Scene类型,我想根据SceneNumber对项目进行排序,SceneNumber是Scene的一个属性,因为它包含数字后跟字母。
我想排序
1
10
15A
2
30B
4B
4A
到
1
2
4A
4B
10
15A
30
这是我目前在Icomparer中所拥有的内容
public class SortScenes : IComparer<string>
{
public int Compare(object x, object y)
{
if (((Scene)x).SceneNumber > ((Scene)y).SceneNumber)
{
return 1;
}
return -1;
}
}
如何通过使用字符串来完成这项工作。
我想实现以下
var nums = "0123456789".ToCharArray();
SceneList.OrderBy(x => x.SceneNumber.LastIndexOfAny(nums)).ThenBy(x => x.SceneNumber))
但是在IComparer中。
答案 0 :(得分:0)
我会考虑将Scene.SceneNumber
拆分为例如数字“主场景”和阿尔法“子场景”。鉴于您的场景声明,我使用RegEx将SceneNumber分割为数字和可选的alpha部分。
请注意,我的IComparer
是IComparer<Scene>
,而不是IComparer<string>
。
namespace SceneSorter
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
class Program
{
static void Main(string[] args)
{
var sceneList = new List<Scene>
{
new Scene { SceneNumber = "1" },
new Scene { SceneNumber = "10" },
new Scene { SceneNumber = "15A" },
new Scene { SceneNumber = "2" },
new Scene { SceneNumber = "30B" },
new Scene { SceneNumber = "4B" },
new Scene { SceneNumber = "4A" }
};
foreach (var scene in sceneList.OrderBy(x => x, new SceneComparer()))
{
Console.WriteLine(scene.SceneNumber);
}
}
}
public class Scene
{
// TODO: Consider splitting SceneNumber into a e.g. a numeric "main scene" and an alpha "sub scene".
public string SceneNumber { get; set; }
}
public class SceneComparer : IComparer<Scene>
{
// Assumes that a scene is either numeric, or numeric + alpha.
private readonly Regex sceneRegEx = new Regex(@"(\d*)(\w*)", RegexOptions.Compiled);
public int Compare(Scene x, Scene y)
{
var firstSceneMatch = this.sceneRegEx.Match(x.SceneNumber);
var firstSceneNumeric = Convert.ToInt32(firstSceneMatch.Groups[1].Value);
var firstSceneAlpha = firstSceneMatch.Groups[2].Value;
var secondSceneMatch = this.sceneRegEx.Match(y.SceneNumber);
var secondSceneNumeric = Convert.ToInt32(secondSceneMatch.Groups[1].Value);
var secondSceneAlpha = secondSceneMatch.Groups[2].Value;
if (firstSceneNumeric < secondSceneNumeric)
{
return -1;
}
if (firstSceneNumeric > secondSceneNumeric)
{
return 1;
}
return string.CompareOrdinal(firstSceneAlpha, secondSceneAlpha);
}
}
}
1
2
4A
4B
10
15A
30B
Press any key to continue . . .
IComparer<string>
看起来非常相似:
public class SceneNumberComparer : IComparer<string>
{
// Assumes that a scene is either numeric, or numeric + alpha.
private readonly Regex sceneRegEx = new Regex(@"(\d*)(\w*)", RegexOptions.Compiled);
public int Compare(string x, string y)
{
var firstSceneMatch = this.sceneRegEx.Match(x);
var firstSceneNumeric = Convert.ToInt32(firstSceneMatch.Groups[1].Value);
var firstSceneAlpha = firstSceneMatch.Groups[2].Value;
var secondSceneMatch = this.sceneRegEx.Match(y);
var secondSceneNumeric = Convert.ToInt32(secondSceneMatch.Groups[1].Value);
var secondSceneAlpha = secondSceneMatch.Groups[2].Value;
if (firstSceneNumeric < secondSceneNumeric)
{
return -1;
}
if (firstSceneNumeric > secondSceneNumeric)
{
return 1;
}
return string.CompareOrdinal(firstSceneAlpha, secondSceneAlpha);
}
}
...由.OrderBy(x => x.SceneNumber, new SceneNumberComparer())
答案 1 :(得分:0)
也许你可以尝试按如下方式实现Compare方法:
public static char[] nums = "0123456789".ToCharArray();
public static int Compare(string x, string y)
{
if (x.LastIndexOfAny(nums) > y.LastIndexOfAny(nums))
{
return 1;
}
if (x.LastIndexOfAny(nums) == y.LastIndexOfAny(nums))
{
return x.CompareTo(y);
}
return -1;
}