Menu
Coddy logo textTech

sort.Interface

חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 74 מתוך 107.

החבילה sort מספקת דוגמה מצוינת נוספת לתכנון המבוסס על ממשקים. כדי למיין אוסף מותאם אישית, הטיפוס שלך חייב לממש את sort.Interface:

type Interface interface {
    Len() int
    Less(i, j int) bool
    Swap(i, j int)
}

שלוש המתודות האלה מספקות לאלגוריתם המיון את כל מה שהוא צריך: את אורך האוסף, דרך להשוות בין איברים ודרך להחליף ביניהם. כך אפשר להפוך פרוסה של מבנים מותאמים אישית לניתנת למיון:

type Person struct {
    Name string
    Age  int
}

type ByAge []Person

func (a ByAge) Len() int           { return len(a) }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

func main() {
    people := []Person{
        {"Alice", 30},
        {"Bob", 25},
        {"Carol", 35},
    }
    
    sort.Sort(ByAge(people))
    fmt.Println(people)
    // [{Bob 25} {Alice 30} {Carol 35}]
}

התובנה המרכזית היא ליצור טיפוס בעל שם (ByAge) המבוסס על הפרוסה שלך. כך אפשר להגדיר התנהגויות מיון שונות לאותם נתונים. אפשר ליצור ByName עם מימוש שונה של Less כדי למיין לפי סדר אלפביתי במקום זאת.

ברגע שהטיפוס שלך מממש את sort.Interface, הוא עובד אוטומטית עם sort.Sort(), sort.Reverse() ועם sort.IsSorted().

challenge icon

אתגר

קל

בואו נבנה מערכת מלאי מוצרים הניתנת למיון, שמדגימה את העוצמה של sort.Interface של Go! תיצרו טיפוס Product ותממשו כמה אסטרטגיות מיון, כך שאפשר יהיה למיין את אותו אוסף בדרכים שונות.

תארגנו את הקוד בשני קבצים:

  • product.go: הגדירו את טיפוס המוצר ואת מימושי המיון.

    צרו מבנה Product עם שלושה שדות: Name (string), Price (float64) ו-Quantity (int).

    צרו שני טיפוסים בעלי שם המבוססים על []Product:

    • ByPrice - למיון מוצרים לפי מחיר בסדר עולה
    • ByQuantity - למיון מוצרים לפי כמות בסדר יורד (הכמות הגדולה ביותר תחילה)

    כל טיפוס צריך לממש את שלוש המתודות הנדרשות על ידי sort.Interface: Len(), Less(i, j int) ו-Swap(i, j int). המתודה Less קובעת את סדר המיון עבור כל טיפוס.

  • main.go: בנו ומיינו את מלאי המוצרים.

    קראו מצב מיון (price או quantity), ואז קראו מספר ואחריו פרטי מוצרים. כל מוצר מסופק בשלוש שורות: שם, מחיר וכמות.

    צרו פרוסה של מוצרים, מיינו אותם באמצעות טיפוס המיון המתאים בהתאם למצב, ואז הדפיסו כל מוצר בפורמט הבא:

    [Name]: $[Price] (x[Quantity])

    הציגו מחירים עם שתי ספרות אחרי הנקודה העשרונית.

הקלטים הבאים יסופקו:

  • שורה 1: מצב מיון (price או quantity)
  • שורה 2: מספר המוצרים
  • השורות הבאות: פרטי המוצרים (שם, מחיר, כמות - שלוש שורות לכל מוצר)

לדוגמה, עבור הקלט:

price
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

הפלט שלכם אמור להיות:

Mouse: $29.99 (x50)
Keyboard: $79.99 (x25)
Laptop: $999.99 (x5)

ועבור הקלט:

quantity
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

הפלט שלכם אמור להיות:

Mouse: $29.99 (x50)
Keyboard: $79.99 (x25)
Laptop: $999.99 (x5)

שימו לב שאפשר למיין את אותם נתוני מוצרים בדרכים שונות, פשוט באמצעות שימוש בטיפוס בעל שם אחר. לאחר שהטיפוסים שלכם עומדים בדרישות של sort.Interface, הם עובדים בצורה חלקה עם sort.Sort() מהספרייה הסטנדרטית.

נסו בעצמכם

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// קרא את מצב המיון
	var mode string
	fmt.Fscanln(reader, &mode)

	// קרא את מספר המוצרים
	var count int
	fmt.Fscanln(reader, &count)

	// קרא את המוצרים
	products := make([]Product, count)
	for i := 0; i < count; i++ {
		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)

		priceStr, _ := reader.ReadString('\n')
		priceStr = strings.TrimSpace(priceStr)
		price, _ := strconv.ParseFloat(priceStr, 64)

		qtyStr, _ := reader.ReadString('\n')
		qtyStr = strings.TrimSpace(qtyStr)
		quantity, _ := strconv.Atoi(qtyStr)

		products[i] = Product{Name: name, Price: price, Quantity: quantity}
	}

	// TODO: מיין את המוצרים לפי mode
	// אם mode הוא "price", השתמש בטיפוס ByPrice
	// אם mode הוא "quantity", השתמש בטיפוס ByQuantity
	// השתמש ב-sort.Sort() עם הטיפוס המתאים

	// TODO: הדפס כל מוצר בפורמט:
	// [Name]: $[Price] (x[Quantity])
	// השתמש ב-fmt.Printf עם %.2f לעיצוב המחיר
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Go אונליין