nodes: 0, module; 1, function_definition; 2, function_name:uniq; 3, parameters; 4, block; 5, identifier:self; 6, default_parameter; 7, default_parameter; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, if_statement; 14, function_definition; 15, expression_statement; 16, return_statement; 17, identifier:isSorted; 18, False; 19, identifier:iterator; 20, None; 21, comment:"""
          Produce a duplicate-free version of the array. If the array has already
          been sorted, you have the option of using a faster algorithm.
          Aliased as `unique`.
          """; 22, assignment; 23, assignment; 24, assignment; 25, assignment; 26, comparison_operator:iterator is not None; 27, block; 28, function_name:by; 29, parameters; 30, block; 31, assignment; 32, call; 33, identifier:ns; 34, call; 35, attribute; 36, list; 37, attribute; 38, attribute; 39, identifier:initial; 40, attribute; 41, identifier:iterator; 42, None; 43, expression_statement; 44, identifier:memo; 45, identifier:value; 46, identifier:index; 47, if_statement; 48, return_statement; 49, identifier:ret; 50, call; 51, attribute; 52, argument_list; 53, attribute; 54, argument_list; 55, identifier:ns; 56, identifier:results; 57, identifier:ns; 58, identifier:array; 59, identifier:self; 60, identifier:obj; 61, identifier:self; 62, identifier:obj; 63, assignment; 64, parenthesized_expression; 65, block; 66, identifier:memo; 67, attribute; 68, argument_list; 69, identifier:self; 70, identifier:_wrap; 71, identifier:ret; 72, identifier:self; 73, identifier:Namespace; 74, identifier:initial; 75, call; 76, conditional_expression:(_.last(memo) != value or
                   not len(memo)) if isSorted else not _.include(memo, value); 77, expression_statement; 78, expression_statement; 79, identifier:_; 80, identifier:reduce; 81, identifier:initial; 82, identifier:by; 83, attribute; 84, argument_list; 85, parenthesized_expression; 86, identifier:isSorted; 87, not_operator; 88, call; 89, call; 90, call; 91, identifier:map; 92, identifier:iterator; 93, boolean_operator; 94, call; 95, attribute; 96, argument_list; 97, attribute; 98, argument_list; 99, identifier:_; 100, argument_list; 101, comparison_operator:_.last(memo) != value; 102, not_operator; 103, attribute; 104, argument_list; 105, identifier:memo; 106, identifier:append; 107, identifier:value; 108, attribute; 109, identifier:append; 110, subscript; 111, attribute; 112, call; 113, identifier:value; 114, call; 115, identifier:_; 116, identifier:include; 117, identifier:memo; 118, identifier:value; 119, identifier:ns; 120, identifier:results; 121, attribute; 122, identifier:index; 123, identifier:ns; 124, identifier:array; 125, attribute; 126, argument_list; 127, identifier:len; 128, argument_list; 129, identifier:ns; 130, identifier:array; 131, identifier:_; 132, identifier:last; 133, identifier:memo; 134, identifier:memo
code: def uniq(self, isSorted=False, iterator=None):
          """
          Produce a duplicate-free version of the array. If the array has already
          been sorted, you have the option of using a faster algorithm.
          Aliased as `unique`.
          """
          ns = self.Namespace()
          ns.results = []
          ns.array = self.obj
          initial = self.obj
          if iterator is not None:
              initial = _(ns.array).map(iterator)
  
          def by(memo, value, index):
              if ((_.last(memo) != value or
                   not len(memo)) if isSorted else not _.include(memo, value)):
                  memo.append(value)
                  ns.results.append(ns.array[index])
  
              return memo
  
          ret = _.reduce(initial, by)
          return self._wrap(ret)