Named slice elements

I’ve got a slice where some elements are special and should be named, but I also want to iterate over the full set easily, I’ll use an analogy:

const Population = struct {
    // element 0 is the teacher
    // elements 1... are the students
    people: []Person,
}

I want something better than just remember magically that index 0 is the teacher. How can I enable this?

Person should either have an enum tag/field or be an enum.

I don’t want to pay the storage cost of an extra field in Person tracking whether its a Teacher or a Student. I know there is only one Teacher.

I guess I could do this:

const Population = struct {
    all: []Person,
    teacher: *Person,
    students: []Person,
}
const Population = struct {
    // element 0 is the teacher
    // elements 1... are the students
    people: []Person,

    const teacher_index = 0;
    const first_student_index = 1;

    pub fn teacher(self: Population) *Person {
        return &self.people[teacher_index];
    }

    pub fn students(self: Population) []Person {
        return self.people[first_student_index..];
    }
}

Could also use enum(usize) { teacher = 0, _ }; for the indexes if you want type safety, but I’m not sure how beneficial that’d be for this use case. See here for an example of that sort of thing.

10 Likes

oops, didnt see sqeek say the same thing

1 Like

Probably not what you’re wanting but focusing on the “I also want to iterate over the full set easily”, could you introduce your own iterator?

For example, it’s stored separately like this to avoid errors and allow individual accesses:

struct {
   teacher: Person,
   students: []Person,
}

but can iterate all like

var it = classroom.allIterator();
while (it.next()) |person| {
 // ...
}