Indexer (programming): Difference between revisions

Content deleted Content added
Adding local short description: "Object-oriented programming concept", overriding Wikidata description "overloadable collection indexing operator"
 
(43 intermediate revisions by 25 users not shown)
Line 1:
{{Short description|Object-oriented programming concept}}
In programming, an '''indexer''' is in [[object-oriented programming]] a kind of smart array that enables the user to get an index of objects held within an object. It is a member of a class that enables the use it like an [[array]]. For instance, in [[C Sharp (programming language)|C#]], it is possible to access with an indexer a class like an array.<ref>{{cite web
In [[object-oriented programming]], an '''indexer''' allows instances of a particular class or struct to be indexed just like arrays.<ref>{{cite web|access-date=2011-08-01 |author=jagadish980 |date=2008-01-29 |website=SURESHKUMAR.NET FORUMS |title=C# - What is an indexer in C# |url=http://forums.sureshkumar.net/vb-asp-net-interview-technical-questions/16320-c-what-indexer-c.html |archive-url=https://web.archive.org/web/20090922193214/http://forums.sureshkumar.net/vb-asp-net-interview-technical-questions/16320-c-what-indexer-c.html |archive-date=September 22, 2009 }}</ref> It is a form of [[operator overloading]].
| accessdate = 2011-08-01
| author = jagadish980
| date = 2008-01-29
| ___location = http://forums.sureshkumar.net/forum.php
| publisher = Bulletin: SURESHKUMAR.NET FORUMS
| title = C# - What is an indexer in C#
| url = http://forums.sureshkumar.net/vb-asp-net-interview-technical-questions/16320-c-what-indexer-c.html}}</ref>
 
== ImplementationImplementations ==
=== C++ ===
Indexers are implemented through the get and set [[Mutator method|accessor]]s for the {{C_sharp|operator[]}}. They are similar to [[Property (programming)|properties]], but differ from them in not being [[Static method|static]]. The get and set accessors are called as methods using the parameter list of the indexer declaration, but the set accessor still has the implicite {{C_sharp|value}} parameter.
In C++ one can emulate indexing by overloading the {{c++|[]}} operator. The expression {{c++|a[b...]}} translates to a call to the user-defined function {{c++|operator[]}} as {{c++|(a).operator[](b...)}}.<ref>{{cite web|url=https://en.cppreference.com/w/cpp/language/operators|title=C++ operator overloading}}</ref> Here is an example,
<syntaxhighlight lang="c++">
struct vector {
int size; double* data;
vector(int n) { size = n; data = new double[n](); }
~vector(){ size = 0; delete[] data; }
double& operator[](int i) { return data[i]; }
};
 
#include <iostream>
== Example ==
 
Here an example of the usage of an indexer in a class:
int main() {
vector v(3);
for (int i = 0; i < v.size; i++) v[i] = i + 1;
for (int i = 0; i < v.size; i++) std::cout << v[i] << "\n";
return 0;
}
</syntaxhighlight>
 
=== C# ===
Indexers are implemented through the get and set [[Mutator method|accessor]]s for the {{C_sharp|operator[]}}. They are similar to [[Property (programming)|properties]], but differ by not being [[Static method|static]], and the fact that indexers' accessors take parameters. The get and set accessors are called as methods using the parameter list of the indexer declaration, but the set accessor still has the implicit {{C_sharp|value}} parameter.
 
==== Example 1====
<syntaxhighlight lang="csharp">
public class Vector
{
private double[] _data;
 
public Vector(int n)
{
_data = new double[n];
}
 
public int Size => _data.Length;
 
public double this[int i]
{
get => _data[i];
set => _data[i] = value;
}
 
public static void Main()
{
var vector = new Vector(3);
for (var i = 0; i < vector.Size; i++)
vector[i] = i + 1;
for (var i = 0; i < vector.Size; i++)
System.Console.WriteLine(vector[i]);
}
}
</syntaxhighlight>
 
==== Example 2====
Here is a C# example of the usage of an indexer in a class:
<ref>{{cite web
| accessdateaccess-date = 2011-08-01
| website= .net Funda
| ___location = http://www.dotnetfunda.com/
| publisher = .net Funda
| title = C# Interview Questions
| url = httphttps://www.dotnetfunda.com/interview/exam4161-what-is-an-indexer-in-csharp-.aspx}}</ref>
 
<sourcesyntaxhighlight lang=Csharp"csharp">
class OurFamilyFamily
{
private long[]List<string> familyMember_familyMembers = new long[7]List<string>();
 
public long this [int index]
public Family(params string[] members)
{
{
// The get accessor
_familyMembers.AddRange(members);
get
}
 
public string this[int index]
{
// The get accessor
get => _familyMembers[index];
 
// The set accessor with
set => _familyMembers[index] = value;
}
 
public int this[string val]
{
// Getting index by value (first element found)
get => _familyMembers.FindIndex(m => m == val);
}
 
public int Length => _familyMembers.Count;
}
</syntaxhighlight>
 
Usage example:
 
<syntaxhighlight lang="csharp">
void Main()
{
var doeFamily = new Family("John", "Jane");
for (int i = 0; i < doeFamily.Length; i++)
{
return familyMember var member = doeFamily[indexi];
var index = doeFamily[member]; // same as i in this case, but it demonstrates indexer overloading allowing to search doeFamily by value.
Console.WriteLine($"{member} is the member number {index} of the {nameof(doeFamily)}");
}
}
</syntaxhighlight>
 
In this example, the indexer is used to get the value at the nth position, and then to get the position in the list referenced by its value.
// The set accessor with
The output of the code is:
set
John is the member number 0 of the doeFamily
{
Jane is the member number 1 of the doeFamily
familyMember[index] = value;
 
=== PHP ===
In [[PHP]] indexing can be implemented via the predefined {{code|ArrayAccess}} interface,<ref>{{cite web|url=https://www.php.net/manual/en/class.arrayaccess.php|title=PHP ArrayAccess interface}}</ref>
<syntaxhighlight lang="php">
class Vector implements ArrayAccess
{
function __construct(int $n) {
$this->size = $n;
$this->data = array_fill(0, $n, 0);
}
 
}
public function offsetGet($offset): mixed {
return $this->data[$offset];
}
 
public function offsetSet($offset, $value): void {
$this->data[$offset] = $value;
}
 
public function offsetExists($offset): bool {}
 
public function offsetUnset($offset): void {}
}
</source>
 
$vector = new Vector(3);
== References ==
 
{{Reflist|2}}
for ($i = 0; $i < $vector->size; $i++) $vector[$i] = $i + 1;
for ($i = 0; $i < $vector->size; $i++) print "{$vector[$i]}\n";
</syntaxhighlight>
 
=== Python ===
In [[Python (programming language)|Python]] one implements indexing by overloading the {{python|__getitem__}} and {{python|__setitem__}} methods,
<syntaxhighlight lang="python">
import array
 
class Vector(object):
def __init__(self, n: int):
self.size = n
self.data = array.array("d", [0.0] * n)
 
def __getitem__(self, i: int):
return self.data[i]
 
def __setitem__(self, i: int, value):
self.data[i] = value
 
vector = Vector(3)
for i in range(vector.size):
vector[i] = i + 1
for i in range(vector.size):
print(vector[i])
</syntaxhighlight>
 
=== Rust ===
[[Rust (programming language)|Rust]] provides the {{Mono|std::ops::Index}} trait.<ref>{{cite web |title=Index in std::ops - Rust |url=https://doc.rust-lang.org/std/ops/trait.Index.html |website=doc.rust-lang.org |access-date=11 January 2025}}</ref>
<syntaxhighlight lang="rust">
use std::ops::Index;
 
enum Nucleotide {
A,
C,
G,
T,
}
 
struct NucleotideCount {
a: usize,
c: usize,
g: usize,
t: usize,
}
 
impl Index<Nucleotide> for NucleotideCount {
type Output = usize;
 
fn index(&self, nucleotide: Nucleotide) -> &Self::Output {
match nucleotide {
Nucleotide::A => &self.a,
Nucleotide::C => &self.c,
Nucleotide::G => &self.g,
Nucleotide::T => &self.t,
}
}
}
 
let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12};
assert_eq!(nucleotide_count[Nucleotide::A], 14);
assert_eq!(nucleotide_count[Nucleotide::C], 9);
assert_eq!(nucleotide_count[Nucleotide::G], 10);
assert_eq!(nucleotide_count[Nucleotide::T], 12);
</syntaxhighlight>
 
=== Smalltalk ===
In [[Smalltalk]] one can emulate indexing by (e.g.) defining the {{smalltalk|get:}} and {{smalltalk|set:value:}} instance methods. For example, in [[GNU Smalltalk]],
<syntaxhighlight lang="smalltalk">
Object subclass: vector [ |data| ]
vector class extend [ new: n [ |v| v:=super new. v init: n. ^v] ]
vector extend [ init: n [ data:= Array new: n ] ]
vector extend [ size [ ^(data size) ] ]
vector extend [ get: i [ ^(data at: i) ] ]
vector extend [ set: i value: x [ data at: i put: x ] ]
v:=vector new: 3
1 to: (v size) do: [:i| v set: i value: (i+1) ]
1 to: (v size) do: [:i| (v get: i) printNl ]
</syntaxhighlight>
 
== See also ==
*{{Portal|Computer [[Property (programming)|Properties]]}}
* [[Mutator method]]
 
== References ==
{{compu-prog-stub}}
{{Reflist}}
 
[[Category:Articles with example C++ code]]
<!--Categories-->
[[Category:Articles with example C Sharp code]]
[[Category:Articles with example Python (programming language) code]]
[[Category:Articles with example PHP code]]
[[Category:Articles with example Rust code]]
[[Category:Programming language topics]]
[[Category:Object-oriented programming]]
[[Category:Operators (programming)]]
 
 
<!--Interwikis-->
{{compu-prog-stub}}