1+ <!DOCTYPE html>
2+ < html >
3+
4+ < head >
5+ < meta charset ="utf-8 ">
6+ < meta http-equiv ="X-UA-Compatible " content ="IE=edge,chrome=1 ">
7+ < title > go-linq: LINQ query functions over slices for Golang</ title >
8+ < meta name ="viewport " content ="width=device-width ">
9+ < link href ="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css " rel ="stylesheet ">
10+ < link rel ="stylesheet " href ="css/main.css ">
11+ < link href ='//fonts.googleapis.com/css?family=Roboto:300 ' rel ='stylesheet ' type ='text/css '>
12+ < meta name ="author " content ="Ahmet Alp Balkan ">
13+
14+ < script type ="text/javascript " src ="//use.typekit.net/wnk8juw.js "> </ script >
15+ < script type ="text/javascript "> try { Typekit . load ( ) ; } catch ( e ) { } </ script >
16+ </ head >
17+
18+ < body >
19+ < header >
20+ < h1 > go-linq</ h1 >
21+
22+ < h2 > .NET's Language Integrated Query (LINQ) library for Go</ h2 >
23+
24+ < p >
25+ Query and manipulate Go slices and collections using SQL-like methods.
26+ < br /> Written in pure Go with no dependencies, tested with 100% code coverage.
27+ </ p >
28+
29+ < div class ='promo '>
30+ < p >
31+ < iframe src ="http://ghbtns.com/github-btn.html?user=ahmetalpbalkan&repo=go-linq&type=watch&count=true&size=large " allowtransparency ="true "
32+ frameborder ="0 " scrolling ="0 " width ="142px " height ="30px " style ='margin-left:30px '> </ iframe >
33+ </ p >
34+
35+ < p >
36+ < a class ='btn btn-default btn-lg ' href ='https://github.com/ahmetalpbalkan/go-linq '> Fork it!</ a >
37+ < a class ='btn btn-default btn-lg ' href ='http://godoc.org/github.com/ahmetalpbalkan/go-linq '> GoDoc</ a >
38+ </ p >
39+
40+ </ header >
41+
42+ < section class ='features '>
43+ < div class ='inner row '>
44+ < aside class ='col-md-4 '>
45+ < h3 > Bring your type</ h3 >
46+ < p >
47+ There are no generics in Go, but
48+ < nobr > go-linq</ nobr > supports arrays, slices, maps, strings and channels out-of-the-box, or any collection
49+ that implements < code > .Comparable</ code > .
50+ </ p >
51+ </ aside >
52+
53+ < aside class ='col-md-4 '>
54+ < h3 > Method syntax</ h3 >
55+ < p style ='text-align: center; '>
56+ < code > From(slice)</ code > < code > .Where(predicate)</ code > < code > .Select(selector)</ code > < code > .ToSlice(&result)</ code >
57+ < br /> Easy as that. Just keep writing your queries.
58+ </ p >
59+ </ aside >
60+
61+ < aside class ='col-md-4 '>
62+ < h3 > Concurrency</ h3 >
63+ < p >
64+ Your queries can share data between goroutines by calling < code > .FromChannel()</ code > and < code > .ToChannel()</ code > methods.
65+ </ p >
66+ </ aside >
67+ </ div >
68+ </ section >
69+
70+ < section class ='demo hidden-xs '>
71+ < h2 > Basic</ h2 >
72+ < p > Find average age of students over 20.</ p >
73+ < div class ='inner row '>
74+ < table >
75+ < tr >
76+ < td class ='docs '>
77+ Import your < code > []Student</ code > .
78+ </ td >
79+
80+ < td class ='code '> < code >
81+ results := From(students).
82+ </ code > </ td >
83+ </ tr >
84+
85+ < tr >
86+ < td class ='docs '>
87+ Find those over 20.< br /> So we make type assertion to our input type.
88+ </ td >
89+
90+ < td class ='code '> < code >
91+ Where(func (s interface{}) bool {< br />
92+ return s.(Student).age > = 20< br />
93+ }).
94+ </ code > </ td >
95+ </ tr >
96+
97+ < tr >
98+ < td class ='docs '>
99+ Select their ages.
100+ </ td >
101+
102+ < td class ='code '> < code >
103+ Select(func (s interface{}) interface{} {< br />
104+ return s.(Student).age< br />
105+ }).
106+ </ code > </ td >
107+ </ tr >
108+ < tr >
109+ < td class ='docs '>
110+ Find the average.
111+ </ td >
112+
113+ < td class ='code '> < code >
114+ Average()
115+ </ code > </ td >
116+ </ tr >
117+ </ table >
118+ </ div >
119+
120+ < h2 > Concurrent</ h2 >
121+ < div class ='inner row '>
122+ < p > Count websites that have a favicon.ico.</ p >
123+ < table >
124+ < tr >
125+ < td class ='docs '>
126+
127+ </ td >
128+
129+ < td class ='code '> < code >
130+ urls := make(chan interface{})< br />
131+ results := make(chan interface{})
132+ </ code > </ td >
133+ </ tr >
134+
135+ < tr >
136+ < td class ='docs '>
137+ Convert domain names to full URLs.
138+ </ td >
139+
140+ < td class ='code '> < code >
141+ go func(domains []string) {< br />
142+ From(domains).Select(func(d interface{}) interface{} {</ br >
143+ return fmt.Sprintf("http://%s/favicon.ico", d)</ br >
144+ }).ToChannel(urls)</ br >
145+ }(domains)
146+ </ code > </ td >
147+ </ tr >
148+
149+ < tr >
150+ < td class ='docs '>
151+ Let's run the following in parallel.< br /> Request favicon for each domain.
152+ </ td >
153+
154+ < td class ='code '> < code >
155+ go func() {< br />
156+ defer close(results)</ br >
157+ var wg sync.WaitGroup</ br >
158+ for url := range urls {</ br >
159+ wg.Add(1)</ br >
160+ go func(url string) {</ br >
161+ defer wg.Done()</ br >
162+ resp, _ := http.Get(url)</ br >
163+ results < - resp.StatusCode </ br >
164+ }(url.(string))</ br >
165+ }</ br >
166+ wg.Wait()</ br >
167+ }()
168+ </ code > </ td >
169+ </ tr >
170+
171+ < tr >
172+ < td class ='docs '>
173+ Count websites.
174+ </ td >
175+
176+ < td class ='code '> < code >
177+ FromChannel(results).CountWith(func(r interface{}) bool {< br />
178+ return r.(int) == 200< br />
179+ })
180+ </ code > </ td >
181+ </ tr >
182+ </ table >
183+ </ section >
184+
185+ < section class ='about '>
186+
187+ < h2 > About</ h2 >
188+ < div class ='inner '>
189+ < p >
190+ If you have suggestions or improvements, feel free to contact or submit a pull request. All contributions are welcomed.
191+ </ p >
192+
193+ < p >
194+ This library is brought you by < a href ='http://kalan.rocks/ '> Alexander (kalan) Kalankhodzhaev</ a >
195+ and < a href ='https://twitter.com/ahmetalpbalkan '> @ahmetalpbalkan</ a > .
196+ </ p >
197+ < p >
198+ < a href ='http://kalan.rocks/ '> < img src ='img/kalan.png ' width ='150 ' height ='150 ' alt ="Alexander (kalan) Kalankhodzhaev, 2016 " /> </ a >
199+ < a href ='http://ahmetalpbalkan.com '> < img src ='img/ahmet.png ' width ='150 ' height ='150 ' alt ="Ahmet Alp Balkan, 2013 " /> </ a >
200+ </ p >
201+
202+ </ div >
203+ </ section >
204+
205+ < footer >
206+ Lovingly made in Moscow and Seattle.
207+ </ footer >
208+
209+ < script >
210+ ( function ( i , s , o , g , r , a , m ) { i [ 'GoogleAnalyticsObject' ] = r ; i [ r ] = i [ r ] || function ( ) {
211+ ( i [ r ] . q = i [ r ] . q || [ ] ) . push ( arguments ) } , i [ r ] . l = 1 * new Date ( ) ; a = s . createElement ( o ) ,
212+ m = s . getElementsByTagName ( o ) [ 0 ] ; a . async = 1 ; a . src = g ; m . parentNode . insertBefore ( a , m )
213+ } ) ( window , document , 'script' , '//www.google-analytics.com/analytics.js' , 'ga' ) ;
214+ ga ( 'create' , 'UA-45321252-3' , 'ahmetalpbalkan.github.io' ) ;
215+ ga ( 'send' , 'pageview' ) ;
216+ </ script >
217+ </ body >
218+
219+ </ html >
0 commit comments