原文:
7 tricks to simplify your programs with LINQ
1. 初始化数组
注意点:
这个方法可以避免 for 循环;
Linq 会动态的产生数组,因此垃圾数组可能在运行时才得到清理,要构造很大的数组,还是用常规的 for 循环比较好。
2. 用一个循环枚举多个数组
普通做法:
技巧:
3. 生成长度为 N 的随机序列
4. 生成字符串
生成长度为 N 的 "ABCABC.." 字符串:
另一个例子:
5. 转换序列或集合
在 C#/VB 中不允许直接将一个类型 T 的序列转换为另一个类型 U 的序列,即使 U 是 T 的父类也不行。这是因为如果允许这样,就可能会产生运行时异常。但用 Linq 可以有一些方法来做类似的转换:
要转换 List<T> 必须通过复制:
或者:
6. 将一个值转换为仅包含它的长度为1的序列
可以创建数组,但用 IEnumerable 会更通用:
7. 遍历序列的全部子集
可以用来解背包问题等。
这个比较难理解一点。
1. 初始化数组
int
[] a
=
Enumerable.Repeat(
-
1
,
10
).ToArray();
int [] b = Enumerable.Range( 0 , 10 ).ToArray();
int [] c = Enumerable.Range( 0 , 10 ).Select(i => 100 + 10 * i).ToArray();
int [] b = Enumerable.Range( 0 , 10 ).ToArray();
int [] c = Enumerable.Range( 0 , 10 ).Select(i => 100 + 10 * i).ToArray();
注意点:
这个方法可以避免 for 循环;
Linq 会动态的产生数组,因此垃圾数组可能在运行时才得到清理,要构造很大的数组,还是用常规的 for 循环比较好。
2. 用一个循环枚举多个数组
普通做法:
foreach
(var x
in
array1) {
DoSomething(x);
}
foreach (var x in array2) {
DoSomething(x);
}
DoSomething(x);
}
foreach (var x in array2) {
DoSomething(x);
}
技巧:
foreach
(var x
in
array1.Concat(array2)) {
DoSomething(x);
}
DoSomething(x);
}
3. 生成长度为 N 的随机序列
Random rand
=
new
Random();
var randomSeq = Enumerable.Repeat( 0 , N).Select(i => rand.Next());
var randomSeq = Enumerable.Repeat( 0 , N).Select(i => rand.Next());
4. 生成字符串
生成长度为 N 的 "ABCABC.." 字符串:
string
str
=
new
string
(
Enumerable.Range( 0 , N)
.Select(i => ( char )(‘A’ + i % 3 ))
.ToArray());
Enumerable.Range( 0 , N)
.Select(i => ( char )(‘A’ + i % 3 ))
.ToArray());
另一个例子:
string
values
=
string
.Join(
string
.Empty, Enumerable.Repeat(pattern, N).ToArray());
5. 转换序列或集合
在 C#/VB 中不允许直接将一个类型 T 的序列转换为另一个类型 U 的序列,即使 U 是 T 的父类也不行。这是因为如果允许这样,就可能会产生运行时异常。但用 Linq 可以有一些方法来做类似的转换:
IEnumerable
<
string
>
strEnumerable
=
…;
IEnumerable < object > objEnumerable = strEnumerable.Cast < object > ();
IEnumerable < object > objEnumerable = strEnumerable.Cast < object > ();
要转换 List<T> 必须通过复制:
List
<
string
>
strList
=
…;
List < object > objList = new List < object > (strList.Cast < object > ());
List < object > objList = new List < object > (strList.Cast < object > ());
或者:
var objList
=
strList.Cast
<
object
>
().ToList();
6. 将一个值转换为仅包含它的长度为1的序列
可以创建数组,但用 IEnumerable 会更通用:
IEnumerable
<
int
>
seq
=
Enumerable.Repeat(myValue,
1
);
7. 遍历序列的全部子集
可以用来解背包问题等。
var arr
=
new
string
[] {
"
foo
"
,
"
bar
"
,
"
xxx
"
};
var subsets = from m in Enumerable.Range( 0 , 1 << arr.Length)
select
from i in Enumerable.Range( 0 , arr.Length)
where (m & ( 1 << i)) != 0
select arr[i];
foreach (var subset in subsets)
{
foreach (var element in subset)
{
Console.Write(element + " " );
}
Console.Write( " /n " );
}
Console.ReadLine();
var subsets = from m in Enumerable.Range( 0 , 1 << arr.Length)
select
from i in Enumerable.Range( 0 , arr.Length)
where (m & ( 1 << i)) != 0
select arr[i];
foreach (var subset in subsets)
{
foreach (var element in subset)
{
Console.Write(element + " " );
}
Console.Write( " /n " );
}
Console.ReadLine();
这个比较难理解一点。