Skip to content

Commit

Permalink
Merge pull request #28 from pedropark99/multi-array
Browse files Browse the repository at this point in the history
Multi array
  • Loading branch information
pedropark99 authored Aug 24, 2024
2 parents f1e0c19 + 046809c commit 69022bb
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 9 deletions.
4 changes: 2 additions & 2 deletions Chapters/09-data-structures.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -879,9 +879,9 @@ pub fn main() !void {

In other words, instead of creating an array of "persons", the `MultiArrayList()` function
creates a "struct of arrays". Each data member of this struct is a different array that stores
the values of a specific field from the `Person` struct values that are added (or, appended) to the "struct of arrays".
the values of a specific field from the `Person` struct values that were added (or, appended) to this "struct of arrays".
One important detail is that each of these separate internal arrays stored inside `PersonArray`
are dynamic arrays. This means that these arrays can grow automatically as needed, to accomodate
are dynamic arrays. This means that these arrays can grow in capacity automatically as needed, to accomodate
more values.

The @fig-multi-array exposed below presents a diagram that describes the `PersonArray` struct
Expand Down
8 changes: 3 additions & 5 deletions _freeze/Chapters/09-data-structures/execute-results/html.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Chapters/09-data-structures.html
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ <h2 data-number="11.4" class="anchored" data-anchor-id="multi-array-structure"><
<span id="cb21-23"><a href="#cb21-23" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span>);</span>
<span id="cb21-24"><a href="#cb21-24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>In other words, instead of creating an array of “persons”, the <code>MultiArrayList()</code> function creates a “struct of arrays”. Each data member of this struct is a different array that stores the values of a specific field from the <code>Person</code> struct values that are added (or, appended) to the “struct of arrays”. One important detail is that each of these separate internal arrays stored inside <code>PersonArray</code> are dynamic arrays. This means that these arrays can grow automatically as needed, to accomodate more values.</p>
<p>In other words, instead of creating an array of “persons”, the <code>MultiArrayList()</code> function creates a “struct of arrays”. Each data member of this struct is a different array that stores the values of a specific field from the <code>Person</code> struct values that were added (or, appended) to this “struct of arrays”. One important detail is that each of these separate internal arrays stored inside <code>PersonArray</code> are dynamic arrays. This means that these arrays can grow in capacity automatically as needed, to accomodate more values.</p>
<p>The <a href="#fig-multi-array" class="quarto-xref">Figure&nbsp;<span>11.5</span></a> exposed below presents a diagram that describes the <code>PersonArray</code> struct that we have created in the previous code example. Notice that the values of the data members present in each of the three <code>Person</code> values that we have appended into the <code>PersonArray</code> object that we have instantiated, are scattered across three different internal arrays of the <code>PersonArray</code> object.</p>
<div id="fig-multi-array" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
Expand Down
2 changes: 1 addition & 1 deletion docs/search.json
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@
"href": "Chapters/09-data-structures.html#multi-array-structure",
"title": "11  Data Structures",
"section": "11.4 Multi array structure",
"text": "11.4 Multi array structure\nZig introduces a new data structure called MultiArrayList(). It is a different version of the dynamic array that we have introduced at Section 11.1. The difference between this structure and the ArrayList() that we know from Section 11.1, is that MultiArrayList() creates a separate dynamic array for each field of the struct that you provide as input.\nConsider the following code example. We create a new custom struct called Person. This struct contains three different data members, or, three different fields. As consequence, when we provide this Person data type as input to MultiArrayList(), this creates a “struct of three different arrays” called PersonArray. In other words, this PersonArray is a struct that contains three internal dynamic arrays in it. One array for each field found in the Person struct definition.\n\nconst std = @import(\"std\");\nconst Person = struct {\n name: []const u8,\n age: u8,\n height: f32,\n};\nconst PersonArray = std.MultiArrayList(Person);\n\npub fn main() !void {\n var gpa = std.heap.GeneralPurposeAllocator(.{}){};\n const allocator = gpa.allocator();\n var people = PersonArray{};\n defer people.deinit(allocator);\n\n try people.append(allocator, .{\n .name = \"Auguste\", .age = 15, .height = 1.54\n });\n try people.append(allocator, .{\n .name = \"Elena\", .age = 26, .height = 1.65\n });\n try people.append(allocator, .{\n .name = \"Michael\", .age = 64, .height = 1.87\n });\n}\n\nIn other words, instead of creating an array of “persons”, the MultiArrayList() function creates a “struct of arrays”. Each data member of this struct is a different array that stores the values of a specific field from the Person struct values that are added (or, appended) to the “struct of arrays”. One important detail is that each of these separate internal arrays stored inside PersonArray are dynamic arrays. This means that these arrays can grow automatically as needed, to accomodate more values.\nThe Figure 11.5 exposed below presents a diagram that describes the PersonArray struct that we have created in the previous code example. Notice that the values of the data members present in each of the three Person values that we have appended into the PersonArray object that we have instantiated, are scattered across three different internal arrays of the PersonArray object.\n\n\n\n\n\n\nFigure 11.5: A diagram of the PersonArray struct.\n\n\n\nYou can easily access each of these arrays separately, and iterate over the values of each array. For that, you will need to call the items() method from the PersonArray object, and provide as input to this method, the name of the field that you want to iterate over. If you want to iterate through the .age array for example, then, you need to call items(.age) from the PersonArray object, like in the example below:\n\nfor (people.items(.age)) |*age| {\n try stdout.print(\"Age: {d}\\n\", .{age.*});\n}\n\nAge: 15\nAge: 26\nAge: 64\nIn the above example, we are iterating over the values of the .age array, or, the internal array of the PersonArray object that contains the values of the age data member from the Person values that were added to the multi array struct.\nIn this example we are calling the items() method directly from the PersonArray object. However, it is recommended on most situations to call this items() method from a “slice object”, which you can create from the slice() method. The reason for this is that calling items() multiple times have better performance if you use a slice object.\nIn other words, if you are planning to access only one of the internal arrays from your “multi array struct”, it is fine to call items() directly from the multi array object. But if you need to access many of the internal arrays from your “multi array struct”, then, you will likely need to call items() more than once, and, in such circustance, is better to call items() through a slice object. The example below demonstrates the use of such object:\n\nvar slice = people.slice();\nfor (slice.items(.age)) |*age| {\n age.* += 10;\n}\nfor (slice.items(.name), slice.items(.age)) |*n,*a| {\n try stdout.print(\n \"Name: {s}, Age: {d}\\n\", .{n.*, a.*}\n );\n}\n\nName: Auguste, Age: 25\nName: Elena, Age: 36\nName: Michael, Age: 74",
"text": "11.4 Multi array structure\nZig introduces a new data structure called MultiArrayList(). It is a different version of the dynamic array that we have introduced at Section 11.1. The difference between this structure and the ArrayList() that we know from Section 11.1, is that MultiArrayList() creates a separate dynamic array for each field of the struct that you provide as input.\nConsider the following code example. We create a new custom struct called Person. This struct contains three different data members, or, three different fields. As consequence, when we provide this Person data type as input to MultiArrayList(), this creates a “struct of three different arrays” called PersonArray. In other words, this PersonArray is a struct that contains three internal dynamic arrays in it. One array for each field found in the Person struct definition.\n\nconst std = @import(\"std\");\nconst Person = struct {\n name: []const u8,\n age: u8,\n height: f32,\n};\nconst PersonArray = std.MultiArrayList(Person);\n\npub fn main() !void {\n var gpa = std.heap.GeneralPurposeAllocator(.{}){};\n const allocator = gpa.allocator();\n var people = PersonArray{};\n defer people.deinit(allocator);\n\n try people.append(allocator, .{\n .name = \"Auguste\", .age = 15, .height = 1.54\n });\n try people.append(allocator, .{\n .name = \"Elena\", .age = 26, .height = 1.65\n });\n try people.append(allocator, .{\n .name = \"Michael\", .age = 64, .height = 1.87\n });\n}\n\nIn other words, instead of creating an array of “persons”, the MultiArrayList() function creates a “struct of arrays”. Each data member of this struct is a different array that stores the values of a specific field from the Person struct values that were added (or, appended) to this “struct of arrays”. One important detail is that each of these separate internal arrays stored inside PersonArray are dynamic arrays. This means that these arrays can grow in capacity automatically as needed, to accomodate more values.\nThe Figure 11.5 exposed below presents a diagram that describes the PersonArray struct that we have created in the previous code example. Notice that the values of the data members present in each of the three Person values that we have appended into the PersonArray object that we have instantiated, are scattered across three different internal arrays of the PersonArray object.\n\n\n\n\n\n\nFigure 11.5: A diagram of the PersonArray struct.\n\n\n\nYou can easily access each of these arrays separately, and iterate over the values of each array. For that, you will need to call the items() method from the PersonArray object, and provide as input to this method, the name of the field that you want to iterate over. If you want to iterate through the .age array for example, then, you need to call items(.age) from the PersonArray object, like in the example below:\n\nfor (people.items(.age)) |*age| {\n try stdout.print(\"Age: {d}\\n\", .{age.*});\n}\n\nAge: 15\nAge: 26\nAge: 64\nIn the above example, we are iterating over the values of the .age array, or, the internal array of the PersonArray object that contains the values of the age data member from the Person values that were added to the multi array struct.\nIn this example we are calling the items() method directly from the PersonArray object. However, it is recommended on most situations to call this items() method from a “slice object”, which you can create from the slice() method. The reason for this is that calling items() multiple times have better performance if you use a slice object.\nIn other words, if you are planning to access only one of the internal arrays from your “multi array struct”, it is fine to call items() directly from the multi array object. But if you need to access many of the internal arrays from your “multi array struct”, then, you will likely need to call items() more than once, and, in such circustance, is better to call items() through a slice object. The example below demonstrates the use of such object:\n\nvar slice = people.slice();\nfor (slice.items(.age)) |*age| {\n age.* += 10;\n}\nfor (slice.items(.name), slice.items(.age)) |*n,*a| {\n try stdout.print(\n \"Name: {s}, Age: {d}\\n\", .{n.*, a.*}\n );\n}\n\nName: Auguste, Age: 25\nName: Elena, Age: 36\nName: Michael, Age: 74",
"crumbs": [
"<span class='chapter-number'>11</span>  <span class='chapter-title'>Data Structures</span>"
]
Expand Down

0 comments on commit 69022bb

Please sign in to comment.