LINQ语法糖
qiezi
2007-05-04
LINQ语法挺诱人的,不过基本上也就是语法糖了,目前的新一代语言都把语法糖作为重点。
D里面简单试验了一下,参考了 http://msdn2.microsoft.com/en-us/library/aa479865.aspx 第一个例子,排序没有实现: import std.stdio; import std.string : toupper; T[] where(T)(T[] s, bool delegate(T) dg) { T[] result; foreach(i; s) if (dg(i)) result ~= i; return result; } T[] orderby(T)(T[] s, int delegate(T,T) dg) { return s; } T[] select(T)(T[] s, T delegate(T) dg) { T[] result; foreach(i; s) result ~= dg(i); return result; } void main() { char[][] names = [ "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" ]; char[][] result = names .where((char[] s){return s.length == 5;}) .orderby((char[] s1, char[] s2){ return -1; }) .select((char[] s){ return s.toupper(); }); foreach(name; result) writefln(name); } 输出: 引用 BURKE FRANK DAVID 排序没有实现。 |
|
qiezi
2007-05-04
第3个例子:
http://msdn2.microsoft.com/en-us/library/aa479865.aspx#linqprojec_topic3 import std.stdio; import std.string : toupper; T[] where(T)(T[] s, bool delegate(T) dg) { T[] result; foreach(i; s) if (dg(i)) result ~= i; return result; } T[] orderby(T)(T[] s, int delegate(T,T) dg) { return s; } T[] select(T)(T[] s, T delegate(T) dg) { T[] result; foreach(i; s) result ~= dg(i); return result; } void main() { char[][] names = [ "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" ]; bool filter(char[] s) { return s.length == 5; } int sortfunc(char[] s1, char[] s2) { return -1; } char[] project(char[] s) { return s.toupper(); } char[][] result = names .where(&filter) .orderby(&sortfunc) .select(&project); foreach(name; result) writefln(name); } 输出: 引用 BURKE FRANK DAVID 排序没有实现。 |
|
qiezi
2007-05-04
可以看到LINQ里面的实现和我这里很相似,它能做到如此简洁归功于它的lambda表达式和松散的函数调用形式。
D目前的函数直接量语法已经精简了许多,但还没有精简到这种程度。 |
|
oldrev
2007-05-04
如果允许像ruby一样当函数有参数时还能省略括号就能达到linq的效果了。
我感觉用mixin还可以简化一下: char[][] result = names .where("s.length == 5") .orderby("-1") .select("s.toupper"); |
|
qiezi
2007-05-04
嗯,不过也不是特别好看亚,会影响编译时错误输出,还是从语言层面上解决比较好。
|
|
qiezi
2007-05-04
又做了个groupby:
import std.stdio; T[][I] groupby(T,I)(T[] s, I delegate(T) dg) { T[][I] result; foreach(item; s) { I i = dg(item); result[i] ~= item; } return result; } void main() { char[][] names = [ "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" ]; char[][][uint] result = names .groupby((char[] s){return s.length;}); foreach(length, names; result) { writefln("Strings of length ", length); foreach(name; names) writefln(name); } } 输出: 引用 Strings of length 5 Burke Frank David Strings of length 6 Connor Albert George Harris Strings of length 7 Everett |
|
qiezi
2007-05-04
Sum:
import std.stdio; I sum(T,I)(T[] s, I delegate(T) dg) { I result; foreach(i; s) result += dg(i); return result; } T sum(T)(T[] s) { T result; foreach(i; s) result += i; return result; } void main() { char[][] names = [ "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" ]; int totalLength = names .sum((char[] s){return s.length;}); writefln("Total length: ", totalLength); int[] arr = [1,2,3,4,5]; writefln("Sum: ", arr.sum()); } 输出: 引用 Total length: 46 Sum: 15 好像到后面就不再是那种第一眼看到的LINQ语法啦,不过那个文档里就是这么写的,我模仿一下而已。。。感觉这不就是FP,或者是ruby的block换了件马甲就出来了? 不过LINQ是针对泛型接口来实现的,应用比较广,我这里仅适合数组。 |
|
DavidL
2007-05-05
相当有意思!像个SQL,不过其实SQL的语法并不好用
|