1"use strict";(globalThis.webpackChunkdocs=globalThis.webpackChunkdocs||[]).push([[3601],{22007(e,n,r){r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>l,metadata:()=>t,toc:()=>o});const t=JSON.parse('{"id":"language/data_types/vectors","title":"Vectors","description":"Explore the Vector data type in Noir. Understand its methods, see real-world examples, and learn how to effectively use Vectors in your Noir programs.","source":"@site/versioned_docs/version-v1.0.0-rc.2/language/data_types/vectors.mdx","sourceDirName":"language/data_types","slug":"/language/data_types/vectors","permalink":"/docs/language/data_types/vectors","draft":false,"unlisted":false,"editUrl":"https://github.com/noir-lang/noir/edit/master/docs/versioned_docs/version-v1.0.0-rc.2/language/data_types/vectors.mdx","tags":[],"version":"v1.0.0-rc.2","frontMatter":{"title":"Vectors","description":"Explore the Vector data type in Noir. Understand its methods, see real-world examples, and learn how to effectively use Vectors in your Noir programs.","keywords":["noir","vector type","methods","examples","subarrays"]},"sidebar":"sidebar","previous":{"title":"Arrays","permalink":"/docs/language/data_types/arrays"},"next":{"title":"Tuples","permalink":"/docs/language/data_types/tuples"}}');var s=r(74848),a=r(28453);const l={title:"Vectors",description:"Explore the Vector data type in Noir. Understand its methods, see real-world examples, and learn how to effectively use Vectors in your Noir programs.",keywords:["noir","vector type","methods","examples","subarrays"]},c=void 0,i={},o=[{value:"Methods",id:"methods",level:2},{value:"push_back",id:"push_back",level:3},{value:"push_front",id:"push_front",level:3},{value:"pop_front",id:"pop_front",level:3},{value:"pop_back",id:"pop_back",level:3},{value:"append",id:"append",level:3},{value:"insert",id:"insert",level:3},{value:"remove",id:"remove",level:3},{value:"len",id:"len",level:3},{value:"as_array",id:"as_array",level:3},{value:"map",id:"map",level:3},{value:"mapi",id:"mapi",level:3},{value:"for_each",id:"for_each",level:3},{value:"for_eachi",id:"for_eachi",level:3},{value:"fold",id:"fold",level:3},{value:"reduce",id:"reduce",level:3},{value:"filter",id:"filter",level:3},{value:"join",id:"join",level:3},{value:"all",id:"all",level:3},{value:"any",id:"any",level:3}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"A vector is a dynamically-sized view into a sequence of elements. They can be resized at runtime, but because they don't own the data, they cannot be returned from a circuit. You can treat vectors as arrays without a constrained size."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn main() -> pub u32 {\n let mut vector: [Field] = @[0; 2];\n\n let mut new_vector = vector.push_back(6);\n new_vector.len()\n}\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To write a vector literal, use a preceding at sign as in: ",(0,s.jsx)(n.code,{children:"@[0; 2]"})," or\n",(0,s.jsx)(n.code,{children:"@[1, 2, 3]"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["It is important to note that vectors are not references to arrays. In Noir,\n",(0,s.jsx)(n.code,{children:"@[..]"})," is more similar to an immutable, growable vector."]}),"\n",(0,s.jsxs)(n.p,{children:["View the corresponding test file ",(0,s.jsx)(n.a,{href:"https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/array_to_vector/src/main.nr",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"methods",children:"Methods"}),"\n",(0,s.jsx)(n.p,{children:"For convenience, the STD provides some ready-to-use, common methods for vectors:"}),"\n",(0,s.jsx)(n.h3,{id:"push_back",children:"push_back"}),"\n",(0,s.jsx)(n.p,{children:"Pushes a new element to the end of the vector, returning a new vector with a length one greater than the original unmodified vector."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn push_back<T>(_self: [T], _elem: T) -> [T]\n"})}),"\n",(0,s.jsx)(n.p,{children:"example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn main() -> pub Field {\n let mut vector: [Field] = @[0; 2];\n\n let mut new_vector = vector.push_back(6);\n new_vector.len()\n}\n"})}),"\n",(0,s.jsxs)(n.p,{children:["View the corresponding test file ",(0,s.jsx)(n.a,{href:"https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/array_to_vector/src/main.nr",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"push_front",children:"push_front"}),"\n",(0,s.jsx)(n.p,{children:"Returns a new vector with the specified element inserted at index 0. The existing elements indexes are incremented by 1."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn push_front(_self: Self, _elem: T) -> Self\n"})}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"let mut new_vector: [Field] = @[];\nnew_vector = new_vector.push_front(20);\nassert(new_vector[0] == 20); // returns true\n"})}),"\n",(0,s.jsxs)(n.p,{children:["View the corresponding test file ",(0,s.jsx)(n.a,{href:"https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/array_to_vector/src/main.nr",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"pop_front",children:"pop_front"}),"\n",(0,s.jsx)(n.p,{children:"Returns a tuple of two items, the first element of the vector and the rest of the vector."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn pop_front(_self: Self) -> (T, Self)\n"})}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"let (first_elem, rest_of_vector) = vector.pop_front();\n"})}),"\n",(0,s.jsxs)(n.p,{children:["View the corresponding test file ",(0,s.jsx)(n.a,{href:"https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/array_to_vector/src/main.nr",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"pop_back",children:"pop_back"}),"\n",(0,s.jsx)(n.p,{children:"Returns a tuple of two items, the beginning of the vector with the last element omitted and the last element."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn pop_back(_self: Self) -> (Self, T)\n"})}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"let (popped_vector, last_elem) = vector.pop_back();\n"})}),"\n",(0,s.jsxs)(n.p,{children:["View the corresponding test file ",(0,s.jsx)(n.a,{href:"https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/array_to_vector/src/main.nr",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"append",children:"append"}),"\n",(0,s.jsx)(n.p,{children:"Loops over a vector and adds it to the end of another."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn append(mut self, other: Self) -> Self\n"})}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"let append = @[1, 2].append(@[3, 4, 5]);\n"})}),"\n",(0,s.jsx)(n.h3,{id:"insert",children:"insert"}),"\n",(0,s.jsx)(n.p,{children:"Inserts an element at a specified index and shifts all following elements by 1."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn insert(_self: Self, _index: u32, _elem: T) -> Self\n"})}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"new_vector = rest_of_vector.insert(2, 100);\nassert(new_vector[2] == 100);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["View the corresponding test file ",(0,s.jsx)(n.a,{href:"https://github.com/noir-lang/noir/blob/master/test_programs/execution_success/array_to_vector/src/main.nr",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"remove",children:"remove"}),"\n",(0,s.jsx)(n.p,{children:"Remove an element at a specified index, shifting all elements after it to the left, returning the altered vector and the removed element."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn remove(_self: Self, _index: u32) -> (Self, T)\n"})}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"let (remove_vector, removed_elem) = vector.remove(3);\n"})}),"\n",(0,s.jsx)(n.h3,{id:"len",children:"len"}),"\n",(0,s.jsx)(n.p,{children:"Returns the length of a vector"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn len(self) -> Field\n"})}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn main() {\n let vector = @[42, 42];\n assert(vector.len() == 2);\n}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"as_array",children:"as_array"}),"\n",(0,s.jsx)(n.p,{children:"Converts this vector into an array."}),"\n",(0,s.jsx)(n.p,{children:"Make sure to specify the size of the resulting array.\nPanics if the resulting array length is different than the vector's length."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn as_array<let N: u32>(self) -> [T; N]\n"})}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn main() {\n let vector = @[5, 6];\n\n // Always specify the length of the resulting array!\n let array: [Field; 2] = vector.as_array();\n\n assert(array[0] == vector[0]);\n assert(array[1] == vector[1]);\n}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"map",children:"map"}),"\n",(0,s.jsx)(n.p,{children:"Applies a function to each element of the vector, returning a new vector containing the mapped elements."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn map<U, Env>(self, f: fn[Env](T) -> U) -> [U]\n"})}),"\n",(0,s.jsx)(n.p,{children:"example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"let a = @[1, 2, 3];\nlet b = a.map(|a| a * 2); // b is now @[2, 4, 6]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"mapi",children:"mapi"}),"\n",(0,s.jsx)(n.p,{children:"Applies a function to each element of the vector, along with its index in the\nvector, returning a new vector containing the mapped elements."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn mapi<U, Env>(self, f: fn[Env](u32, T) -> U) -> [U]\n"})}),"\n",(0,s.jsx)(n.p,{children:"example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"let a = @[1, 2, 3];\nlet b = a.mapi(|i, a| i + a * 2); // b is now @[2, 5, 8]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"for_each",children:"for_each"}),"\n",(0,s.jsx)(n.p,{children:"Applies a function to each element of the vector."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn for_each<Env>(self, f: fn[Env](T) -> ())\n"})}),"\n",(0,s.jsx)(n.p,{children:"example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'let a = @[1, 2, 3];\na.for_each(|x| {\n println(f"{x}");\n});\n// prints:\n// 1\n// 2\n// 3\n'})}),"\n",(0,s.jsx)(n.h3,{id:"for_eachi",children:"for_eachi"}),"\n",(0,s.jsx)(n.p,{children:"Applies a function to each element of the vector, along with its index in the\nvector."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn for_eachi<Env>(self, f: fn[Env](u32, T) -> ())\n"})}),"\n",(0,s.jsx)(n.p,{children:"example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'let a = @[1, 2, 3];\na.for_eachi(|i, x| {\n println(f"{i}, {x}");\n});\n// prints:\n// 0, 1\n// 1, 2\n// 2, 3\n'})}),"\n",(0,s.jsx)(n.h3,{id:"fold",children:"fold"}),"\n",(0,s.jsx)(n.p,{children:"Applies a function to each element of the vector, returning the final accumulated value. The first\nparameter is the initial value."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn fold<U, Env>(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U\n"})}),"\n",(0,s.jsx)(n.p,{children:"This is a left fold, so the given function will be applied to the accumulator and first element of\nthe vector, then the second, and so on. For a given call the expected result would be equivalent to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"let a1 = @[1];\nlet a2 = @[1, 2];\nlet a3 = @[1, 2, 3];\n\nlet f = |a, b| a - b;\na1.fold(10, f) //=> f(10, 1)\na2.fold(10, f) //=> f(f(10, 1), 2)\na3.fold(10, f) //=> f(f(f(10, 1), 2), 3)\n"})}),"\n",(0,s.jsx)(n.p,{children:"example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\nfn main() {\n let vector = @[2, 2, 2, 2, 2];\n let folded = vector.fold(0, |a, b| a + b);\n assert(folded == 10);\n}\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"reduce",children:"reduce"}),"\n",(0,s.jsx)(n.p,{children:"Same as fold, but uses the first element as the starting element."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn reduce<Env>(self, f: fn[Env](T, T) -> T) -> T\n"})}),"\n",(0,s.jsx)(n.p,{children:"example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn main() {\n let vector = @[2, 2, 2, 2, 2];\n let reduced = vector.reduce(|a, b| a + b);\n assert(reduced == 10);\n}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"filter",children:"filter"}),"\n",(0,s.jsx)(n.p,{children:"Returns a new vector containing only elements for which the given predicate returns true."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn filter<Env>(self, f: fn[Env](T) -> bool) -> Self\n"})}),"\n",(0,s.jsx)(n.p,{children:"example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn main() {\n let vector = @[1, 2, 3, 4, 5];\n let odds = vector.filter(|x| x % 2 == 1);\n assert_eq(odds, @[1, 3, 5]);\n}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"join",children:"join"}),"\n",(0,s.jsxs)(n.p,{children:["Flatten each element in the vector into one value, separated by ",(0,s.jsx)(n.code,{children:"separator"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Note that although vectors implement ",(0,s.jsx)(n.code,{children:"Append"}),", ",(0,s.jsx)(n.code,{children:"join"})," cannot be used on vector\nelements since nested vectors are prohibited."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn join(self, separator: T) -> T where T: Append\n"})}),"\n",(0,s.jsx)(n.p,{children:"example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'struct Accumulator {\n total: Field,\n}\n\n// "Append" two accumulators by adding them\nimpl Append for Accumulator {\n fn empty() -> Self {\n Self { total: 0 }\n }\n\n fn append(self, other: Self) -> Self {\n Self { total: self.total + other.total }\n }\n}\n\nfn main() {\n let vector = @[1, 2, 3, 4, 5].map(|total| Accumulator { total });\n\n let result = vector.join(Accumulator::empty());\n assert_eq(result, Accumulator { total: 15 });\n\n // We can use a non-empty separator to insert additional elements to sum:\n let separator = Accumulator { total: 10 };\n let result = vector.join(separator);\n assert_eq(result, Accumulator { total: 55 });\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"all",children:"all"}),"\n",(0,s.jsx)(n.p,{children:"Returns true if all the elements satisfy the given predicate"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn all<Env>(self, predicate: fn[Env](T) -> bool) -> bool\n"})}),"\n",(0,s.jsx)(n.p,{children:"example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn main() {\n let vector = @[2, 2, 2, 2, 2];\n let all = vector.all(|a| a == 2);\n assert(all);\n}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"any",children:"any"}),"\n",(0,s.jsx)(n.p,{children:"Returns true if any of the elements satisfy t
1he given predicate"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn any<Env>(self, predicate: fn[Env](T) -> bool) -> bool\n"})}),"\n",(0,s.jsx)(n.p,{children:"example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"fn main() {\n let vector = @[2, 2, 2, 2, 5];\n let any = vector.any(|a| a == 5);\n assert(any);\n}\n\n"})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453(e,n,r){r.d(n,{R:()=>l,x:()=>c});var t=r(96540);const s={},a=t.createContext(s);function l(e){const n=t.useContext(a);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.