Class: Array

Inherits:
Object
  • Object
show all
Defined in:
(unknown)

Instance Method Summary collapse

Instance Method Details

#collapse(args) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'ext/array_collapse/array_collapse.c', line 5

VALUE method_collapse(VALUE self, VALUE args) {
  long len = RARRAY_LEN(self);
  VALUE result = rb_ary_new2(len);
  VALUE stack = rb_ary_new();
  st_table *seen_nodes;
  st_data_t id;
  seen_nodes = st_init_numtable();
  st_insert(seen_nodes, (st_data_t)self, (st_data_t)Qtrue);

#ifdef LOGGING
  FILE *f = fopen("clog.txt", "w");
  if (f == NULL) {
    printf("no log file found\n");
    exit(1);
  }
  fprintf(f, "len: %lu\n", len);
  fprintf(f, "array: %s\n", RSTRING_PTR(rb_ary_to_s(self)));
#endif

  rb_ary_push(stack,self);
  while(RARRAY_LEN(stack) > 0) {
    VALUE array = rb_ary_pop(stack);
    long i;
    for(i = 0; i < RARRAY_LEN(array); i++) {
      VALUE e = RARRAY_AREF(array,i);
      id = (st_data_t)e;
      if (st_lookup(seen_nodes, id, 0)) {
        // drop recursive node
        break;
      }
      switch (TYPE(e)) {
        case T_ARRAY:
          st_insert(seen_nodes, id, (st_data_t)Qtrue);
          rb_ary_push(stack, e);
          break;
        default:
          if (rb_block_given_p()) {
            e = rb_yield(e);
          }
          if (!NIL_P(e)) {
            rb_ary_push(result, e);
          }
          break;
      }
    }
  }
  st_free_table(seen_nodes);
  return result;
}