Unity中ScriptableObject列表多维度排序实现问题(非Lambda)
解决方案
按Amount字段实现升序/降序排序
你已经通过IComparable<FoodScriptableObject>实现了默认的升序排序,在此基础上可以通过两种方式实现降序:
方式1:升序后反转列表
如果要保留原列表,先创建副本再操作,避免修改原数据:
// 升序排序(复用已实现的IComparable逻辑) List<FoodScriptableObject> sortedAsc = new List<FoodScriptableObject>(originalList); sortedAsc.Sort(); // 降序排序:对升序列表执行反转 List<FoodScriptableObject> sortedDesc = new List<FoodScriptableObject>(originalList); sortedDesc.Sort(); sortedDesc.Reverse();
方式2:自定义降序比较器
实现IComparer<FoodScriptableObject>接口,直接定义降序逻辑,无需反转:
public class FoodAmountDescComparer : IComparer<FoodScriptableObject> { public int Compare(FoodScriptableObject x, FoodScriptableObject y) { // 反转升序逻辑,返回y.Amount与x.Amount的比较结果 return y.Amount.CompareTo(x.Amount); } }
使用时传入比较器实例:
List<FoodScriptableObject> sortedDesc = new List<FoodScriptableObject>(originalList); sortedDesc.Sort(new FoodAmountDescComparer());
按Rarity枚举或其他字段排序
通过实现自定义IComparer<T>比较器类来实现不同字段的排序,完全不需要Lambda表达式:
按Rarity枚举升序排序
假设你的Rarity枚举定义为public enum Rarity { Common, Uncommon, Rare, Legendary },直接比较枚举的内置整数值即可:
public class FoodRarityAscComparer : IComparer<FoodScriptableObject> { public int Compare(FoodScriptableObject x, FoodScriptableObject y) { return x.Rarity.CompareTo(y.Rarity); } }
调用示例:
List<FoodScriptableObject> sortedByRarityAsc = new List<FoodScriptableObject>(originalList); sortedByRarityAsc.Sort(new FoodRarityAscComparer());
按Rarity枚举降序排序
只需反转比较逻辑:
public class FoodRarityDescComparer : IComparer<FoodScriptableObject> { public int Compare(FoodScriptableObject x, FoodScriptableObject y) { return y.Rarity.CompareTo(x.Rarity); } }
按其他字段排序(如名称字符串)
以名称字段为例,实现字符串比较的比较器:
public class FoodNameAscComparer : IComparer<FoodScriptableObject> { public int Compare(FoodScriptableObject x, FoodScriptableObject y) { // 使用指定的字符串比较规则,避免文化差异导致的排序问题 return string.Compare(x.Name, y.Name, StringComparison.Ordinal); } }
关键注意点
- 复制列表时
new List<FoodScriptableObject>(originalList)仅拷贝引用,这对排序操作完全足够(排序只改变列表内元素的引用顺序,不修改ScriptableObject实例本身)。如果你之前复制列表没解决问题,大概率是没正确使用自定义比较器,或是反转操作的时机错误。 - 确保
FoodScriptableObject类中的Amount、Rarity、Name等字段是可访问的(设为public,或提供public的getter方法)。
内容的提问来源于stack exchange,提问作者Rudolf
相关产品推荐
相关产品推荐

