| 
									
										
										
										
											2019-10-17 14:11:51 +03:00
										 |  |  | // Copyright © 2018 Inanc Gumus | 
					
						
							|  |  |  | // Learn Go Programming Course | 
					
						
							|  |  |  | // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2019-10-30 19:34:44 +03:00
										 |  |  | // For more tutorials  : https://learngoprogramming.com | 
					
						
							|  |  |  | // In-person training  : https://www.linkedin.com/in/inancgumus/ | 
					
						
							|  |  |  | // Follow me on twitter: https://twitter.com/inancgumus | 
					
						
							| 
									
										
										
										
											2019-10-17 14:11:51 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"sort" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // product is now *product because sorting will unnecessarily copy the product values | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type list []*product | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (l list) String() string { | 
					
						
							|  |  |  | 	if len(l) == 0 { | 
					
						
							|  |  |  | 		return "Sorry. We're waiting for delivery 🚚.\n" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var str strings.Builder | 
					
						
							|  |  |  | 	for _, p := range l { | 
					
						
							| 
									
										
										
										
											2019-10-17 20:23:45 +03:00
										 |  |  | 		// fmt.Printf("* %s\n", p) | 
					
						
							|  |  |  | 		str.WriteString("* ") | 
					
						
							|  |  |  | 		str.WriteString(p.String()) | 
					
						
							|  |  |  | 		str.WriteRune('\n') | 
					
						
							| 
									
										
										
										
											2019-10-17 14:11:51 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return str.String() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (l list) discount(ratio float64) { | 
					
						
							|  |  |  | 	for _, p := range l { | 
					
						
							|  |  |  | 		p.discount(ratio) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-21 12:45:12 +03:00
										 |  |  | // implementation of the sort.Interface: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-17 14:11:51 +03:00
										 |  |  | // by default `list` sorts by `title`. | 
					
						
							|  |  |  | func (l list) Len() int           { return len(l) } | 
					
						
							|  |  |  | func (l list) Less(i, j int) bool { return l[i].title < l[j].title } | 
					
						
							| 
									
										
										
										
											2019-10-21 12:45:12 +03:00
										 |  |  | func (l list) Swap(i, j int)      { l[i], l[j] = l[j], l[i] } | 
					
						
							| 
									
										
										
										
											2019-10-17 14:11:51 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | // byRelease sorts by product release dates. | 
					
						
							|  |  |  | type byRelease struct { | 
					
						
							|  |  |  | 	// byRelease embeds `list` and reuses list's Len and Swap methods. | 
					
						
							|  |  |  | 	list | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-21 12:45:12 +03:00
										 |  |  | // Less takes priority over the Less method of the `list`. | 
					
						
							|  |  |  | // `sort.Sort` will first call this method instead of the `list`'s Less method. | 
					
						
							| 
									
										
										
										
											2019-12-04 12:12:23 +03:00
										 |  |  | func (br byRelease) Less(i, j int) bool { | 
					
						
							| 
									
										
										
										
											2019-10-21 12:45:12 +03:00
										 |  |  | 	// `Before()` accepts a `time.Time` but `released` is not `time.Time`. | 
					
						
							| 
									
										
										
										
											2019-12-04 12:12:23 +03:00
										 |  |  | 	return br.list[i].released.Before(br.list[j].released.Time) | 
					
						
							| 
									
										
										
										
											2019-10-17 14:11:51 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-21 12:45:12 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  | Anonymous embedding means auto-forwarding method calls to the embedded value: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-04 12:12:23 +03:00
										 |  |  | func (br byRelease) Len() int      { return br.list.Len() } | 
					
						
							|  |  |  | func (br byRelease) Swap(i, j int) { br.list.Swap(i, j)   } | 
					
						
							| 
									
										
										
										
											2019-10-21 12:45:12 +03:00
										 |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func byReleaseDate(l list) sort.Interface { | 
					
						
							| 
									
										
										
										
											2019-12-04 12:12:23 +03:00
										 |  |  | 	return &byRelease{l} | 
					
						
							| 
									
										
										
										
											2019-10-21 12:45:12 +03:00
										 |  |  | } |