diff --git a/examples/arrays.ion b/examples/arrays.ion
index 5280cddd8afa807c6b65f80d031137e5484e780d..cf4ce3895bdd2d9d64ff638271db5ace5f5b8e75 100644
--- a/examples/arrays.ion
+++ b/examples/arrays.ion
@@ -1,3 +1,5 @@
+# Standard Arrays
+
 let array = [1  [2 3]  4 [5 6]]
 for i in @array
     echo $i
@@ -7,6 +9,8 @@ for i in [1  [2 3]  4 [5 6]]
     echo $i
 end
 
+# Array Command Substitution
+
 let array_process = @[echo a  b c d    e]
 for i in @array_process
     echo $i
@@ -16,11 +20,30 @@ for i in @[echo a  b c d    e]
     echo $i
 end
 
+# Array Concatenation
+
 let new_array = [@array @array_process]
 for i in @new_array
     echo $i
 end
 
+# As Command Arguments
+
 echo @array
 echo @array_process
 echo @new_array
+
+# Slice by ID
+
+let array = [ 1 2 3 ]
+echo @array[0]
+echo @array[1]
+echo @array[2]
+
+echo [ 1 2 3 ][0]
+echo [ 1 2 3 ][1]
+echo [ 1 2 3 ][2]
+
+echo @[echo 1 2 3][0]
+echo @[echo 1 2 3][1]
+echo @[echo 1 2 3][2]
diff --git a/examples/arrays.out b/examples/arrays.out
index 0e888b876689d80e77c53eddb0b29237e8220080..194f2c62b3166c8be284ab0b51c7d70add7c4675 100644
--- a/examples/arrays.out
+++ b/examples/arrays.out
@@ -34,3 +34,12 @@ e
 1 2 3 4 5 6
 a b c d e
 1 2 3 4 5 6 a b c d e
+1
+2
+3
+1
+2
+3
+1
+2
+3
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 63d90f5bf782f6cafb81a0aa100743adf59ee5db..a77ec4bd2ee01946ea0bbef5b5d5ee20b9918b45 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -25,7 +25,8 @@ pub fn expand_string<'a>(original: &'a str, vars: &Variables, dir_stack: &Direct
         array: &|array: &str, index: Index| {
             match vars.get_array(array) {
                 Some(array) => match index {
-                        Index::All => Some(array.to_owned())
+                        Index::All    => Some(array.to_owned()),
+                        Index::ID(id) => array.get(id).map(|x| vec![x.to_owned()])
                 },
                 None => None
             }
diff --git a/src/parser/shell_expand/mod.rs b/src/parser/shell_expand/mod.rs
index 2e0c6fcb5968d991305c08c9a98208e23abf257d..01c378696524b29a05fc13c3c4cb461ef3bb616b 100644
--- a/src/parser/shell_expand/mod.rs
+++ b/src/parser/shell_expand/mod.rs
@@ -66,10 +66,17 @@ fn expand_brace(current: &mut String, expanders: &mut Vec<Vec<String>>,
 }
 
 fn expand_array(elements: &[&str], expand_func: &ExpanderFunctions) -> Vec<String> {
-    elements.iter().flat_map(|element| expand_string(element, expand_func, false))
+    elements.iter()
+        .flat_map(|element| expand_string(element, expand_func, false))
         .collect()
 }
 
+fn array_nth(elements: &[&str], expand_func: &ExpanderFunctions, id: usize) -> String {
+    elements.iter()
+        .flat_map(|element| expand_string(element, expand_func, false))
+        .nth(id).unwrap_or_default()
+}
+
 #[allow(cyclomatic_complexity)]
 /// Performs shell expansions to an input string, efficiently returning the final expanded form.
 /// Shells must provide their own batteries for expanding tilde and variable words.
@@ -93,22 +100,32 @@ pub fn expand_string(original: &str, expand_func: &ExpanderFunctions, reverse_qu
             for word in token_buffer.drain(..) {
                 match word {
                     WordToken::Array(elements, index) => {
-                        let expanded = match index {
-                            Index::All => expand_array(&elements, expand_func)
+                        match index {
+                            Index::All => {
+                                let expanded = expand_array(&elements, expand_func);
+                                current.push_str(&expanded.join(" "));
+                            },
+                            Index::ID(id) => {
+                                let expanded = array_nth(&elements, expand_func, id);
+                                current.push_str(&expanded);
+                            },
                         };
-                        current.push_str(&expanded.join(" "));
                     },
                     WordToken::ArrayVariable(array, _, index) => {
                         if let Some(array) = (expand_func.array)(array, index) {
                             current.push_str(&array.join(" "));
                         }
                     },
-                    // TODO: Handle Indexing
                     WordToken::ArrayProcess(command, quoted, index) => {
                         let quoted = if reverse_quoting { !quoted } else { quoted };
                         match index {
                             Index::All => {
                                 expand_process(&mut current, command, quoted, expand_func);
+                            },
+                            Index::ID(id) => {
+                                let mut temp = String::new();
+                                expand_process(&mut temp, command, quoted, expand_func);
+                                current.push_str(temp.split_whitespace().nth(id).unwrap_or_default());
                             }
                         }
                     },
@@ -150,7 +167,8 @@ pub fn expand_string(original: &str, expand_func: &ExpanderFunctions, reverse_qu
             match token_buffer[0].clone() {
                 WordToken::Array(elements, index) => {
                     return match index {
-                        Index::All => expand_array(&elements, expand_func)
+                        Index::All    => expand_array(&elements, expand_func),
+                        Index::ID(id) => vec![array_nth(&elements, expand_func, id)],
                     };
                 },
                 WordToken::ArrayVariable(array, quoted, index) => {
@@ -165,9 +183,13 @@ pub fn expand_string(original: &str, expand_func: &ExpanderFunctions, reverse_qu
                     match index {
                         Index::All => {
                             expand_process(&mut output, command, quoted, expand_func);
+                            return output.split_whitespace().map(String::from).collect::<Vec<String>>();
+                        },
+                        Index::ID(id) => {
+                            expand_process(&mut output, command, quoted, expand_func);
+                            return vec![output.split_whitespace().nth(id).unwrap_or_default().to_owned()];
                         }
                     }
-                    return output.split_whitespace().map(String::from).collect::<Vec<String>>();
                 }
                 _ => ()
             }
@@ -176,10 +198,16 @@ pub fn expand_string(original: &str, expand_func: &ExpanderFunctions, reverse_qu
         for word in token_buffer.drain(..) {
             match word {
                 WordToken::Array(elements, index) => {
-                    let expanded = match index {
-                        Index::All => expand_array(&elements, expand_func)
+                    match index {
+                        Index::All    => {
+                            let expanded = expand_array(&elements, expand_func);
+                            output.push_str(&expanded.join(" "));
+                        },
+                        Index::ID(id) => {
+                            let expanded = array_nth(&elements, expand_func, id);
+                            output.push_str(&expanded);
+                        },
                     };
-                    output.push_str(&expanded.join(" "));
                 },
                 WordToken::ArrayVariable(array, _, index) => {
                     if let Some(array) = (expand_func.array)(array, index) {
@@ -191,6 +219,11 @@ pub fn expand_string(original: &str, expand_func: &ExpanderFunctions, reverse_qu
                     match index {
                         Index::All => {
                             expand_process(&mut output, command, quoted, expand_func);
+                        },
+                        Index::ID(id) => {
+                            let mut temp = String::new();
+                            expand_process(&mut temp, command, quoted, expand_func);
+                            output.push_str(temp.split_whitespace().nth(id).unwrap_or_default());
                         }
                     }
                 },
diff --git a/src/parser/shell_expand/words.rs b/src/parser/shell_expand/words.rs
index 657ca6998aa35c2a73b3976b6d7aa878ae9427c3..77ca8742ff977faa2ad9afcaa599a29481273eeb 100644
--- a/src/parser/shell_expand/words.rs
+++ b/src/parser/shell_expand/words.rs
@@ -1,3 +1,5 @@
+use std::str::FromStr;
+
 // Bit Twiddling Guide:
 // var & FLAG != 0 checks if FLAG is enabled
 // var & FLAG == 0 checks if FLAG is disabled
@@ -13,7 +15,23 @@ const DQUOTE: u8 = 4;
 #[derive(Debug, PartialEq, Copy, Clone)]
 pub enum Index {
     // TODO: Ranged and ID
-    All
+    All,
+    ID(usize),
+}
+
+pub enum IndexError {
+    Invalid
+}
+
+impl FromStr for Index {
+    type Err = IndexError;
+    fn from_str(data: &str) -> Result<Index, IndexError> {
+        if let Ok(index) = data.parse::<usize>() {
+            return Ok(Index::ID(index))
+        }
+
+        Ok(Index::All)
+    }
 }
 
 #[derive(Debug, PartialEq, Clone)]
@@ -119,6 +137,26 @@ impl<'a> WordIterator<'a> {
         WordToken::Variable(&self.data[start..], self.flags & DQUOTE != 0)
     }
 
+    fn read_index<I>(&mut self, iterator: &mut I) -> Index
+        where I: Iterator<Item = u8>
+    {
+        self.read += 1;
+        let start = self.read;
+        while let Some(character) = iterator.next() {
+            if let b']' = character {
+                let index = match self.data[start..self.read].parse::<Index>() {
+                    Ok(index) => index,
+                    Err(_)    => Index::All
+                };
+                self.read += 1;
+                return index
+            }
+            self.read += 1;
+        }
+
+        panic!()
+    }
+
     /// Contains the logic for parsing array variable syntax
     fn array_variable<I>(&mut self, iterator: &mut I) -> WordToken<'a>
         where I: Iterator<Item = u8>
@@ -127,8 +165,14 @@ impl<'a> WordIterator<'a> {
         self.read += 1;
         while let Some(character) = iterator.next() {
             match character {
-                // TODO: Detect Index
                 // TODO: ArrayFunction
+                b'[' => {
+                    return WordToken::ArrayVariable (
+                        &self.data[start..self.read],
+                        self.flags & DQUOTE != 0,
+                        self.read_index(iterator)
+                    );
+                },
                 // Only alphanumerical and underscores are allowed in variable names
                 0...47 | 58...64 | 91...94 | 96 | 123...127 => {
                     return WordToken::ArrayVariable(&self.data[start..self.read], self.flags & DQUOTE != 0, Index::All);
@@ -195,10 +239,22 @@ impl<'a> WordIterator<'a> {
                 },
                 b']' if self.flags & SQUOTE == 0 => {
                     if level == 0 {
-                        // TODO: Detect Index
-                        let output = &self.data[start..self.read];
+                        let array_process_contents = &self.data[start..self.read];
                         self.read += 1;
-                        return WordToken::ArrayProcess(output, self.flags & DQUOTE != 0, Index::All);
+                        return if let Some(&b'[') = self.data.as_bytes().get(self.read) {
+                            let _ = iterator.next();
+                            WordToken::ArrayProcess (
+                                array_process_contents,
+                                self.flags & DQUOTE != 0,
+                                self.read_index(iterator)
+                            )
+                        } else {
+                            WordToken::ArrayProcess (
+                                array_process_contents,
+                                self.flags & DQUOTE != 0,
+                                Index::All
+                            )
+                        }
                     } else {
                         level -= 1;
                     }
@@ -279,7 +335,14 @@ impl<'a> WordIterator<'a> {
                     if level == 0 {
                         elements.push(&self.data[start..self.read]);
                         self.read += 1;
-                        return WordToken::Array(elements, Index::All);
+
+                        return if let Some(&b'[') = self.data.as_bytes().get(self.read) {
+                            let _ = iterator.next();
+                            WordToken::Array(elements, self.read_index(iterator))
+                        } else {
+                            WordToken::Array(elements, Index::All)
+
+                        }
                     } else {
                         level -= 1;
                     }
diff --git a/src/shell/assignments.rs b/src/shell/assignments.rs
index 66d706599e74bb9f092465e452b983bd42ea0ccd..61708022d5517e43c39ef8e3600bc80a4bab1b90 100644
--- a/src/shell/assignments.rs
+++ b/src/shell/assignments.rs
@@ -49,7 +49,8 @@ pub fn let_assignment<'a>(original: &'a str, vars: &mut Variables, dir_stack: &D
             array: &|array: &str, index: Index| {
                 match vars.get_array(array) {
                     Some(array) => match index {
-                            Index::All => Some(array.to_owned())
+                            Index::All => Some(array.to_owned()),
+                            Index::ID(id) => array.get(id).map(|x| vec![x.to_owned()])
                     },
                     None => None
                 }