Krushnal Patel
Krushnal Patel

Reputation: 444

Initialize array of arrays with different sizes in Golang

In Golang, I want to initialize an array of arrays which can represent an year. The main array will have 12 sub-arrays each will represent a month. Each subarray will have size of the month they represent.

For eg, 0th sub-array will reference January and will contain 31 elements, 1st sub-array will reference February and will contain 29 elements (considering a leap year) and so on...

Multi-dimensional arrays are initialized like [12][30]int in Golang considering the fixed size. But here, I am working with a multidimensional array of different sizes. How do I initialize a variable with such a datatype?

In short, I want to do something like this:

var year [[31]int, [29]int, [31]int, [30]int, [31]int, [30]int, [31]int, [31]int, [30]int, [31]int, [30]int, [31]int]

But I am struggling with the syntax. Could someone please help me out? Thanks!!

Upvotes: 0

Views: 6442

Answers (3)

BlankXu
BlankXu

Reputation: 11

if you want to initialize an array of arrays which can represent an year and multi-dimensional arrays are initialized like [12][30]int, I think this code may solve your problem:

package main

import (
    "errors"
    "fmt"
    "log"
    "strconv"
    "time"
)

func main() {
    years := []int{
        2022,
        1972,
        2021,
        2020,
    }

    var s string
    for _, year := range years {
        s = ""
        ret, err := GetYearDays(year)
        if err != nil {
            log.Fatal(err)
        }
        for i := range ret {
            s = s + " " + strconv.Itoa(len(ret[i]))
        }
        log.Printf("year: %d, month days:%s\n", year, s)
    }
}

func GetYearDays(year int) (ret [12][]int, err error) {
    // year check depends on the user
    if year < 1952 || year > 3000 {
        return ret, errors.New("invalid year")
    }

    for idx := range ret {
        firstDay, err := time.Parse("2006-1-2", fmt.Sprintf("%d-%d-1", year, idx+1))
        if err != nil {
            return ret, fmt.Errorf("time invalid, year: %d, month: %d", year, idx+1)
        }
        lastDay := firstDay.AddDate(0, 1, -1)
        ret[idx] = make([]int, lastDay.Day())
    }
    return ret, err
}

Upvotes: 1

Sebry
Sebry

Reputation: 137

A slightly more consistent answer reference @Sakib. And I assumed you wanted the dates to be filled too.

days := []int{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
months := make([][]int, len(days))
for i := 0; i < 12; i++ {
    months[i] = make([]int, days[i])
    for j := 0; j < days[i]; j++ {
        months[i][j] = j + 1
    }
    fmt.Println(i+1, months[i])
}

Upvotes: 2

Sakib Md Al Amin
Sakib Md Al Amin

Reputation: 334

You want something like this?

package main

import "fmt"

func main() {
    days := []int{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    months := [12][]int{}
    for i := 0; i < 12; i++ {
        months[i] = make([]int, days[i])
        fmt.Println(i, months[i], len(months[i]))
    }
}

run in go playground

Upvotes: 2

Related Questions