Skip to content

Commit 69022bb

Browse files
authored
Merge pull request #28 from pedropark99/multi-array
Multi array
2 parents f1e0c19 + 046809c commit 69022bb

File tree

4 files changed

+7
-9
lines changed

4 files changed

+7
-9
lines changed

Chapters/09-data-structures.qmd

+2-2
Original file line numberDiff line numberDiff line change
@@ -879,9 +879,9 @@ pub fn main() !void {
879879

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

887887
The @fig-multi-array exposed below presents a diagram that describes the `PersonArray` struct

_freeze/Chapters/09-data-structures/execute-results/html.json

+3-5
Large diffs are not rendered by default.

docs/Chapters/09-data-structures.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ <h2 data-number="11.4" class="anchored" data-anchor-id="multi-array-structure"><
753753
<span id="cb21-23"><a href="#cb21-23" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span>);</span>
754754
<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>
755755
</div>
756-
<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>
756+
<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>
757757
<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>
758758
<div id="fig-multi-array" class="quarto-float quarto-figure quarto-figure-center anchored">
759759
<figure class="quarto-float quarto-float-fig figure">

docs/search.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@
874874
"href": "Chapters/09-data-structures.html#multi-array-structure",
875875
"title": "11  Data Structures",
876876
"section": "11.4 Multi array structure",
877-
"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",
877+
"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",
878878
"crumbs": [
879879
"<span class='chapter-number'>11</span>  <span class='chapter-title'>Data Structures</span>"
880880
]

0 commit comments

Comments
 (0)