数组类型
在c#中给数组去重有多种方法,以下是几种常用的方式:
1.使用 linq 的 distinct() 方法(最常用)
using system;
using system.linq;
int[] numbers = { 1, 2, 2, 3, 4, 4, 5 };
string[] fruits = { "apple", "orange", "apple", "banana" };
// 整数数组去重
int[] uniquenumbers = numbers.distinct().toarray();
// 字符串数组去重
string[] uniquefruits = fruits.distinct().toarray();
// 显示结果
console.writeline(string.join(", ", uniquenumbers)); // 1, 2, 3, 4, 5
console.writeline(string.join(", ", uniquefruits)); // apple, orange, banana
2.使用 hashset(自动去重)
using system;
using system.collections.generic;
int[] numbers = { 1, 2, 2, 3, 4, 4, 5 };
// 方法1:直接创建hashset
hashset<int> hashset = new hashset<int>(numbers);
int[] uniquenumbers = hashset.toarray();
// 方法2:使用hashset收集不重复元素
hashset<int> set = new hashset<int>();
list<int> result = new list<int>();
foreach (int num in numbers)
{
if (set.add(num)) // 如果成功添加(表示不重复)
{
result.add(num);
}
}
int[] uniquearray = result.toarray();
3.使用 linq 的 groupby 方法
using system;
using system.linq;
int[] numbers = { 1, 2, 2, 3, 4, 4, 5 };
int[] uniquenumbers = numbers
.groupby(x => x)
.select(g => g.key)
.toarray();
4.自定义去重方法(不依赖linq)
using system;
using system.collections.generic;
public static t[] removeduplicates<t>(t[] array)
{
list<t> result = new list<t>();
hashset<t> seen = new hashset<t>();
foreach (t item in array)
{
if (seen.add(item)) // 如果元素是新出现的
{
result.add(item);
}
}
return result.toarray();
}
// 使用示例
int[] numbers = { 1, 2, 2, 3, 4, 4, 5 };
int[] uniquenumbers = removeduplicates(numbers);
5.针对复杂对象的去重
using system;
using system.linq;
public class person
{
public int id { get; set; }
public string name { get; set; }
}
person[] people =
{
new person { id = 1, name = "alice" },
new person { id = 2, name = "bob" },
new person { id = 1, name = "alice" } // 重复
};
// 根据id去重
person[] uniquepeople = people
.groupby(p => p.id)
.select(g => g.first())
.toarray();
// 根据多个属性去重
person[] uniquepeople2 = people
.groupby(p => new { p.id, p.name })
.select(g => g.first())
.toarray();
6.保留原始顺序的去重方法
using system;
using system.collections.generic;
public static t[] removeduplicateskeeporder<t>(t[] array)
{
var seen = new hashset<t>();
var result = new list<t>();
foreach (var item in array)
{
if (!seen.contains(item))
{
seen.add(item);
result.add(item);
}
}
return result.toarray();
}
性能比较
- 对于简单数据类型:
distinct().toarray()通常是最佳选择,代码简洁且性能良好 - 对于大型数组:使用
hashset的方法性能更好,时间复杂度为 o(n) - 如果需要保留顺序:使用自定义方法或
distinct()(它也会保留顺序)
简单示例
using system;
using system.linq;
class program
{
static void main()
{
// 示例1:基本去重
int[] numbers = { 1, 2, 3, 2, 4, 3, 5 };
int[] unique = numbers.distinct().toarray();
// 示例2:字符串去重
string[] words = { "hello", "world", "hello", "c#" };
string[] uniquewords = words.distinct().toarray();
// 示例3:使用自定义比较器
string[] caseinsensitive = { "hello", "hello", "world", "world" };
string[] uniquecaseinsensitive = caseinsensitive
.distinct(stringcomparer.ordinalignorecase)
.toarray();
}
}
推荐使用:对于大多数情况,使用 distinct().toarray() 是最简单直接的方法。如果需要处理自定义比较逻辑或特定性能需求,再考虑其他方法。
list<>类型
对于 list<string> 类型的去重操作,方法与数组类似但更灵活,以下是几种常用方式:
1.使用 linq 的 distinct() 方法(推荐)
using system;
using system.collections.generic;
using system.linq;
list<string> fruits = new list<string> { "apple", "orange", "apple", "banana", "orange" };
// 方法1:转换为新list
list<string> uniquefruits1 = fruits.distinct().tolist();
// 方法2:就地修改(去除重复项后重新赋值)
fruits = fruits.distinct().tolist();
// 显示结果
console.writeline(string.join(", ", uniquefruits1)); // apple, orange, banana
2.使用 hashset 的构造函数(高效去重)
list<string> fruits = new list<string> { "apple", "orange", "apple", "banana", "orange" };
// 方法1:直接创建hashset再转回list
hashset<string> hashset = new hashset<string>(fruits);
list<string> uniquefruits = hashset.tolist();
// 方法2:使用hashset构造函数并指定比较器(如忽略大小写)
hashset<string> caseinsensitiveset = new hashset<string>(
fruits,
stringcomparer.ordinalignorecase
);
list<string> uniquecaseinsensitive = caseinsensitiveset.tolist();
3.使用 foreach 循环和 contains 检查
list<string> fruits = new list<string> { "apple", "orange", "apple", "banana", "orange" };
list<string> uniquelist = new list<string>();
foreach (string fruit in fruits)
{
if (!uniquelist.contains(fruit))
{
uniquelist.add(fruit);
}
}
// 或者使用foreach方法
list<string> uniquelist2 = new list<string>();
fruits.foreach(fruit =>
{
if (!uniquelist2.contains(fruit))
uniquelist2.add(fruit);
});
4.使用 linq 的 groupby 方法
list<string> fruits = new list<string> { "apple", "orange", "apple", "banana", "orange" };
list<string> uniquefruits = fruits
.groupby(f => f)
.select(g => g.key)
.tolist();
5.扩展方法(封装重用)
using system;
using system.collections.generic;
using system.linq;
public static class listextensions
{
// 扩展方法:去除重复项(返回新list)
public static list<t> removeduplicates<t>(this list<t> list)
{
return list.distinct().tolist();
}
// 扩展方法:去除重复项(就地修改)
public static void removeduplicatesinplace<t>(this list<t> list)
{
var uniqueitems = list.distinct().tolist();
list.clear();
list.addrange(uniqueitems);
}
// 扩展方法:使用自定义比较器去重
public static list<t> removeduplicates<t>(
this list<t> list,
iequalitycomparer<t> comparer)
{
return list.distinct(comparer).tolist();
}
}
// 使用示例
list<string> fruits = new list<string> { "apple", "orange", "apple", "banana", "orange" };
// 使用扩展方法
list<string> unique1 = fruits.removeduplicates();
fruits.removeduplicatesinplace();
// 使用自定义比较器(忽略大小写)
list<string> mixedcase = new list<string> { "apple", "apple", "orange", "orange" };
list<string> unique2 = mixedcase.removeduplicates(stringcomparer.ordinalignorecase);
6.处理大小写敏感的去重
list<string> mixedcase = new list<string> { "apple", "apple", "orange", "orange", "banana", "banana" };
// 方法1:全部转换为小写/大写后去重
list<string> uniquelower = mixedcase
.select(s => s.tolower())
.distinct()
.tolist();
// 方法2:使用忽略大小写的比较器
list<string> uniquecaseinsensitive = mixedcase
.distinct(stringcomparer.ordinalignorecase)
.tolist();
// 方法3:保留原始大小写形式(第一次出现的)
list<string> uniquepreservecase = mixedcase
.groupby(s => s, stringcomparer.ordinalignorecase)
.select(g => g.first())
.tolist();
7.性能优化的去重方法
public static list<string> removeduplicatesfast(list<string> list)
{
if (list == null || list.count == 0)
return new list<string>();
hashset<string> seen = new hashset<string>();
list<string> result = new list<string>();
foreach (string item in list)
{
if (seen.add(item)) // 如果成功添加到hashset(说明是新的)
{
result.add(item);
}
}
return result;
}
// 或者使用容量优化
public static list<string> removeduplicatesoptimized(list<string> list)
{
if (list == null || list.count == 0)
return new list<string>();
hashset<string> seen = new hashset<string>(list.count); // 预设容量
list<string> result = new list<string>(list.count); // 预设容量
foreach (string item in list)
{
if (seen.add(item))
{
result.add(item);
}
}
result.trimexcess(); // 释放多余容量
return result;
}
8.完整示例
using system;
using system.collections.generic;
using system.linq;
class program
{
static void main()
{
// 创建示例数据
list<string> fruits = new list<string>
{
"apple", "orange", "apple", "banana", "orange", "grape", "banana"
};
console.writeline("原始列表: " + string.join(", ", fruits));
// 方法1:使用distinct
list<string> method1 = fruits.distinct().tolist();
console.writeline("distinct方法: " + string.join(", ", method1));
// 方法2:使用hashset
list<string> method2 = new hashset<string>(fruits).tolist();
console.writeline("hashset方法: " + string.join(", ", method2));
// 方法3:就地修改
fruits = fruits.distinct().tolist();
console.writeline("就地修改后: " + string.join(", ", fruits));
// 处理大小写敏感的场景
list<string> casesensitive = new list<string>
{
"apple", "apple", "apple", "orange", "orange"
};
console.writeline("\n大小写敏感列表: " + string.join(", ", casesensitive));
// 忽略大小写去重
list<string> caseinsensitive = casesensitive
.distinct(stringcomparer.ordinalignorecase)
.tolist();
console.writeline("忽略大小写去重: " + string.join(", ", caseinsensitive));
}
}
性能比较和建议
distinct().tolist()- 最简洁,适用于大多数场景hashset<t>构造函数- 性能最好,特别适合大数据量foreach + contains- 最简单易懂,但性能最差(o(n²))
推荐选择:
- 一般情况:使用
fruits.distinct().tolist() - 性能敏感:使用
new hashset<string>(fruits).tolist() - 需要自定义比较:使用
distinct(stringcomparer.ordinalignorecase).tolist()
以上就是c#数组去重的方法汇总的详细内容,更多关于c#数组去重方法的资料请关注代码网其它相关文章!
发表评论