s_matrix 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -12
- data/ext/s_matrix/gmatx.cpp +20 -2
- data/ext/s_matrix/gmatx.h +6 -1
- data/ext/s_matrix/matx_hash_util.cpp +62 -0
- data/ext/s_matrix/matx_hash_util.h +20 -0
- data/ext/s_matrix/s_matrix.cpp +84 -36
- data/lib/s_matrix/version.rb +1 -1
- data/spec/smatrix_spec.rb +26 -0
- data/todolist.txt +7 -8
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0a1d9986c5eee4c83153245c8ecb30da21d3609
|
4
|
+
data.tar.gz: 8cd70ce3cf6a73ac9acb964b3bb7483979c1686e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6840c3d37d7b86ebb9c2034a7cf295587daff1ac5be8273a2c8bf3eabf33593b0ab334807c9dc3bfaa8dfec2817d312ec017371e15f93bf8f77e728dc678ce52
|
7
|
+
data.tar.gz: 2b33b8b9209bf4c262ea642684bc2332d326e30fc0cecedf5b72c56b10d6958b52f280a0df37cf22862fdbb971244922e4262ac216ae2a6e671e777add55bdb9
|
data/README.md
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
Current version 1.0.
|
2
|
-
Latest stable version is 1.0.0
|
1
|
+
Current version 1.0.2
|
3
2
|
|
4
3
|
### Matrix reduce memory usage for large Hash.
|
5
4
|
Matrix store the hash like this: <br>
|
@@ -46,16 +45,21 @@ Or install it yourself as:
|
|
46
45
|
EQUIPMENTS.size.should == 2
|
47
46
|
# or you can use get\_row instead of []<br>
|
48
47
|
EQUIPMENTS.get\_row('20002')<br>
|
49
|
-
# each
|
50
|
-
EQUIPMENTS.each {|k, v| k == '10001', v == {'id' => '10001', 'name' => 'sword', ...} }
|
51
|
-
# all
|
52
|
-
EQUIPMENTS.all.should == { '20002' => {'id' => '10002', 'name' => 'shoe', 'speed' => '5'}, '20003' => {} }
|
53
|
-
#
|
54
|
-
EQUIPMENTS.
|
55
|
-
#
|
56
|
-
EQUIPMENTS.
|
57
|
-
#
|
58
|
-
|
48
|
+
# each<br>
|
49
|
+
EQUIPMENTS.each {|k, v| k == '10001', v == {'id' => '10001', 'name' => 'sword', ...} }<br>
|
50
|
+
# all<br>
|
51
|
+
EQUIPMENTS.all.should == { '20002' => {'id' => '10002', 'name' => 'shoe', 'speed' => '5'}, '20003' => {} }<br>
|
52
|
+
# first<br>
|
53
|
+
EQUIPMENTS.first.should == ['20002', {'id' => '10002', 'name' => 'shoe', 'speed' => '5'}]
|
54
|
+
# ids<br>
|
55
|
+
EQUIPMENTS.ids.should == ['20002', '20003']<br>
|
56
|
+
# keys<br>
|
57
|
+
EQUIPMENTS.keys.should == ['id', 'name', 'hp']<br>
|
58
|
+
# find -- find the first one<br>
|
59
|
+
EQUIPMENTS.find({name: 'shoe'}).should == ['20002', {'id' => '10002', 'name' => 'shoe', 'speed' => '5'}]
|
60
|
+
# to\_s for debug<br>
|
61
|
+
puts EQUIPMENTS.to_s<br>
|
62
|
+
|
59
63
|
|
60
64
|
### todolist
|
61
65
|
https://github.com/libinzhangyuan/s\_matrix/blob/master/todolist.txt
|
data/ext/s_matrix/gmatx.cpp
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
#include "stdio.h"
|
6
6
|
|
7
7
|
|
8
|
+
bool GMatx::t_continue = true;
|
9
|
+
bool GMatx::t_break = false;
|
8
10
|
GMatx::GMatx(void)
|
9
11
|
{
|
10
12
|
}
|
@@ -43,7 +45,6 @@ const std::vector<std::string>& GMatx::get_titles(void) const
|
|
43
45
|
return m_titles.get_titles();
|
44
46
|
}
|
45
47
|
|
46
|
-
// typedef void (*each_call_func)(const std::string& /*key*/, const t_key_value_hash& /*row_content*/, void* args);
|
47
48
|
void GMatx::each_call(each_call_func func, void* args) const
|
48
49
|
{
|
49
50
|
const std::vector<std::string>& titles = m_titles.get_titles();
|
@@ -52,7 +53,8 @@ void GMatx::each_call(each_call_func func, void* args) const
|
|
52
53
|
{
|
53
54
|
const std::string& id = iter->first;
|
54
55
|
const MatxRow& row = iter->second;
|
55
|
-
func(id, row.to_key_value_hash(titles), args)
|
56
|
+
if (func(id, row.to_key_value_hash(titles), args) == GMatx::t_break)
|
57
|
+
break;
|
56
58
|
}
|
57
59
|
}
|
58
60
|
|
@@ -70,3 +72,19 @@ size_t GMatx::size(void) const
|
|
70
72
|
{
|
71
73
|
return m_contents.size();
|
72
74
|
}
|
75
|
+
|
76
|
+
t_key_value_hash GMatx::first(std::string& id_out) const
|
77
|
+
{
|
78
|
+
t_key_value_hash result;
|
79
|
+
|
80
|
+
// empty matx.
|
81
|
+
//
|
82
|
+
std::map<std::string /* id */, MatxRow>::const_iterator iter = m_contents.begin();
|
83
|
+
if (iter == m_contents.end())
|
84
|
+
return result;
|
85
|
+
|
86
|
+
id_out = iter->first;
|
87
|
+
const MatxRow& row = iter->second;
|
88
|
+
const std::vector<std::string>& titles = m_titles.get_titles();
|
89
|
+
return row.to_key_value_hash(titles);
|
90
|
+
}
|
data/ext/s_matrix/gmatx.h
CHANGED
@@ -19,9 +19,14 @@ public:
|
|
19
19
|
std::string to_s(void) const;
|
20
20
|
size_t size(void) const;
|
21
21
|
|
22
|
+
t_key_value_hash first(std::string& id_out) const;
|
23
|
+
|
22
24
|
// iterator function
|
23
25
|
// the args parameter of each_call function will pass to callback function each_call_func.
|
24
|
-
|
26
|
+
// the return of each_call_func indicate continue iterator or not. - true means continue. false means break.
|
27
|
+
static bool t_continue;
|
28
|
+
static bool t_break;
|
29
|
+
typedef bool (*each_call_func)(const std::string& /*id*/, const t_key_value_hash& /*row_content*/, void* args);
|
25
30
|
void each_call(each_call_func func, void* args) const;
|
26
31
|
|
27
32
|
private:
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#include <sstream>
|
2
|
+
|
3
|
+
#include "matx_hash_util.h"
|
4
|
+
#include "stdio.h"
|
5
|
+
#include "matx_row.h"
|
6
|
+
|
7
|
+
namespace MatxHashUtil
|
8
|
+
{
|
9
|
+
|
10
|
+
VALUE key_value_hash_to_ruby_hash(const t_key_value_hash& row_hash)
|
11
|
+
{
|
12
|
+
VALUE ret_hash = rb_hash_new();
|
13
|
+
for (t_key_value_hash::const_iterator iter = row_hash.begin(); iter != row_hash.end(); ++iter)
|
14
|
+
{
|
15
|
+
const std::string& key = iter->first;
|
16
|
+
const std::string& value = iter->second;
|
17
|
+
if (value == MatxRow::null_string)
|
18
|
+
rb_hash_aset(ret_hash, rb_str_new_cstr(key.c_str()), Qnil);
|
19
|
+
else
|
20
|
+
rb_hash_aset(ret_hash, rb_str_new_cstr(key.c_str()), rb_str_new_cstr(value.c_str()));
|
21
|
+
}
|
22
|
+
return ret_hash;
|
23
|
+
}
|
24
|
+
|
25
|
+
int hash_iter_func(VALUE key, VALUE value, VALUE p_row_hash)
|
26
|
+
{
|
27
|
+
t_key_value_hash* p_hash = (t_key_value_hash*)p_row_hash;
|
28
|
+
|
29
|
+
// key
|
30
|
+
VALUE key_str = rb_funcall(key, rb_intern("to_s"), 0);
|
31
|
+
|
32
|
+
// value
|
33
|
+
std::string str_value;
|
34
|
+
if (TYPE(value) == T_NIL)
|
35
|
+
str_value = MatxRow::null_string;
|
36
|
+
else
|
37
|
+
{
|
38
|
+
VALUE rb_str = rb_funcall(value, rb_intern("to_s"), 0);
|
39
|
+
str_value = StringValueCStr( rb_str );
|
40
|
+
}
|
41
|
+
|
42
|
+
(*p_hash)[StringValueCStr(key_str)] = str_value;
|
43
|
+
return ST_CONTINUE;
|
44
|
+
}
|
45
|
+
|
46
|
+
t_key_value_hash rb_hash_to_key_value_hash(VALUE rb_hash)
|
47
|
+
{
|
48
|
+
t_key_value_hash row_hash;
|
49
|
+
rb_hash_foreach(rb_hash, (int (*)(ANYARGS))hash_iter_func, (VALUE)&row_hash);
|
50
|
+
return row_hash;
|
51
|
+
}
|
52
|
+
|
53
|
+
std::string key_value_hash_to_str(const t_key_value_hash& row_hash)
|
54
|
+
{
|
55
|
+
std::ostringstream ostr;
|
56
|
+
ostr << "--row_hash: size = " << row_hash.size() << std::endl;
|
57
|
+
for (t_key_value_hash::const_iterator iter = row_hash.begin(); iter!= row_hash.end(); ++iter)
|
58
|
+
ostr << iter->first << " -> " << iter->second << std::endl;
|
59
|
+
ostr << std::endl;
|
60
|
+
return ostr.str();
|
61
|
+
}
|
62
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#ifndef _MATX_HASH_UTIL_H_
|
2
|
+
#define _MATX_HASH_UTIL_H_
|
3
|
+
|
4
|
+
#include <string>
|
5
|
+
#include <map>
|
6
|
+
#include "matx_type_def.h"
|
7
|
+
|
8
|
+
#include "ruby.h"
|
9
|
+
|
10
|
+
namespace MatxHashUtil
|
11
|
+
{
|
12
|
+
VALUE key_value_hash_to_ruby_hash(const t_key_value_hash& row_hash);
|
13
|
+
t_key_value_hash rb_hash_to_key_value_hash(VALUE rb_hash);
|
14
|
+
|
15
|
+
std::string key_value_hash_to_str(const t_key_value_hash& row_hash);
|
16
|
+
}
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
#endif // _MATX_HASH_UTIL_H_
|
data/ext/s_matrix/s_matrix.cpp
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#include "ruby/util.h"
|
5
5
|
|
6
6
|
#include "gmatx.h"
|
7
|
+
#include "matx_hash_util.h"
|
7
8
|
|
8
9
|
static VALUE t_init(VALUE self);
|
9
10
|
static VALUE t_init_copy(VALUE self, VALUE orig);
|
@@ -51,19 +52,6 @@ static VALUE sm_alloc(VALUE klass)
|
|
51
52
|
return Data_Wrap_Struct(klass, 0, free_matx, pMatx);
|
52
53
|
}
|
53
54
|
|
54
|
-
static int t_add_row_hash_iter_func(VALUE key, VALUE value, VALUE p_row_hash)
|
55
|
-
{
|
56
|
-
t_key_value_hash* p_hash = (t_key_value_hash*)p_row_hash;
|
57
|
-
|
58
|
-
VALUE key_str = rb_funcall(key, rb_intern("to_s"), 0);
|
59
|
-
VALUE value_str = rb_funcall(value, rb_intern("to_s"), 0);
|
60
|
-
//printf("key: %s, value: %s, p_hash size %lu\n", StringValueCStr(key_str), StringValueCStr(value_str), p_hash->size());
|
61
|
-
|
62
|
-
(*p_hash)[StringValueCStr(key_str)] = StringValueCStr(value_str);
|
63
|
-
return ST_CONTINUE;
|
64
|
-
}
|
65
|
-
|
66
|
-
|
67
55
|
// row: {hp: 23, name: '2332342', 'text' => 'fsdfsd'}
|
68
56
|
static VALUE t_add_row(VALUE self, VALUE id, VALUE row)
|
69
57
|
{
|
@@ -80,8 +68,7 @@ static VALUE t_add_row(VALUE self, VALUE id, VALUE row)
|
|
80
68
|
|
81
69
|
// 处理row deal with row
|
82
70
|
//
|
83
|
-
t_key_value_hash row_hash;
|
84
|
-
rb_hash_foreach(row, (int (*)(ANYARGS))t_add_row_hash_iter_func, (VALUE)&row_hash);
|
71
|
+
const t_key_value_hash& row_hash = MatxHashUtil::rb_hash_to_key_value_hash(row);
|
85
72
|
|
86
73
|
// 存数据 store data
|
87
74
|
//
|
@@ -93,21 +80,6 @@ static VALUE t_add_row(VALUE self, VALUE id, VALUE row)
|
|
93
80
|
return self;
|
94
81
|
}
|
95
82
|
|
96
|
-
static VALUE row_hash_to_ruby_hash(const t_key_value_hash& row_hash)
|
97
|
-
{
|
98
|
-
VALUE ret_hash = rb_hash_new();
|
99
|
-
for (t_key_value_hash::const_iterator iter = row_hash.begin(); iter != row_hash.end(); ++iter)
|
100
|
-
{
|
101
|
-
const std::string& key = iter->first;
|
102
|
-
const std::string& value = iter->second;
|
103
|
-
if (value == MatxRow::null_string)
|
104
|
-
rb_hash_aset(ret_hash, rb_str_new_cstr(key.c_str()), Qnil);
|
105
|
-
else
|
106
|
-
rb_hash_aset(ret_hash, rb_str_new_cstr(key.c_str()), rb_str_new_cstr(value.c_str()));
|
107
|
-
}
|
108
|
-
return ret_hash;
|
109
|
-
}
|
110
|
-
|
111
83
|
static VALUE t_get_row(VALUE self, VALUE id)
|
112
84
|
{
|
113
85
|
// 处理id deal with id
|
@@ -123,12 +95,69 @@ static VALUE t_get_row(VALUE self, VALUE id)
|
|
123
95
|
Data_Get_Struct(self, class GMatx, pMatx);
|
124
96
|
|
125
97
|
t_key_value_hash row_hash = pMatx->get_row(std::string(p_id_c_str));
|
126
|
-
return
|
98
|
+
return MatxHashUtil::key_value_hash_to_ruby_hash(row_hash);
|
99
|
+
}
|
100
|
+
|
101
|
+
struct FindCallbackArgs
|
102
|
+
{
|
103
|
+
std::string id;
|
104
|
+
t_key_value_hash row_content;
|
105
|
+
|
106
|
+
t_key_value_hash search_keys;
|
107
|
+
};
|
108
|
+
static bool callback_func__find(const std::string& id, const t_key_value_hash& row_content, void* args)
|
109
|
+
{
|
110
|
+
FindCallbackArgs* pargs = (FindCallbackArgs*)(args);
|
111
|
+
for (t_key_value_hash::const_iterator iter = pargs->search_keys.begin();
|
112
|
+
iter != pargs->search_keys.end(); ++iter)
|
113
|
+
{
|
114
|
+
const std::string& search_key = iter->first;
|
115
|
+
const std::string& search_value = iter->second;
|
116
|
+
|
117
|
+
t_key_value_hash::const_iterator row_content_iter = row_content.find(search_key);
|
118
|
+
|
119
|
+
// compare nil value. -- s.find({a: '3', b: nil}) when compile b: nil
|
120
|
+
if (search_value == MatxRow::null_string)
|
121
|
+
{
|
122
|
+
if (row_content_iter != row_content.end() && row_content_iter->second != search_value)
|
123
|
+
return GMatx::t_continue;
|
124
|
+
continue;
|
125
|
+
}
|
126
|
+
|
127
|
+
// compare value not nil
|
128
|
+
if (row_content_iter == row_content.end() || row_content_iter->second != search_value)
|
129
|
+
return GMatx::t_continue;
|
130
|
+
}
|
131
|
+
pargs->id = id;
|
132
|
+
pargs->row_content = row_content;
|
133
|
+
return GMatx::t_break;
|
127
134
|
}
|
128
135
|
|
129
|
-
static
|
136
|
+
static VALUE t_find(VALUE self, VALUE search_keys_ruby_hash)
|
130
137
|
{
|
131
|
-
|
138
|
+
Check_Type(search_keys_ruby_hash, T_HASH);
|
139
|
+
|
140
|
+
struct FindCallbackArgs args;
|
141
|
+
args.search_keys = MatxHashUtil::rb_hash_to_key_value_hash(search_keys_ruby_hash);
|
142
|
+
|
143
|
+
class GMatx* pMatx = NULL;
|
144
|
+
Data_Get_Struct(self, class GMatx, pMatx);
|
145
|
+
pMatx->each_call(callback_func__find, &args);
|
146
|
+
if (args.id.size() > 0)
|
147
|
+
{
|
148
|
+
VALUE ret_ary = rb_ary_new();
|
149
|
+
rb_ary_push(ret_ary, rb_str_new_cstr(args.id.c_str()));
|
150
|
+
rb_ary_push(ret_ary, MatxHashUtil::key_value_hash_to_ruby_hash(args.row_content));
|
151
|
+
return ret_ary;
|
152
|
+
}
|
153
|
+
return Qnil;
|
154
|
+
}
|
155
|
+
|
156
|
+
|
157
|
+
static bool callback_func__each(const std::string& key, const t_key_value_hash& row_content, void* args)
|
158
|
+
{
|
159
|
+
rb_yield_values(2, rb_str_new_cstr(key.c_str()), MatxHashUtil::key_value_hash_to_ruby_hash(row_content));
|
160
|
+
return GMatx::t_continue;
|
132
161
|
}
|
133
162
|
|
134
163
|
static VALUE t_each(VALUE self)
|
@@ -144,10 +173,11 @@ static VALUE t_each(VALUE self)
|
|
144
173
|
return self;
|
145
174
|
}
|
146
175
|
|
147
|
-
static
|
176
|
+
static bool callback_func__all(const std::string& key, const t_key_value_hash& row_content, void* args)
|
148
177
|
{
|
149
178
|
VALUE* p_ret_hash = (VALUE*)(args);
|
150
|
-
rb_hash_aset(*p_ret_hash, rb_str_new_cstr(key.c_str()),
|
179
|
+
rb_hash_aset(*p_ret_hash, rb_str_new_cstr(key.c_str()), MatxHashUtil::key_value_hash_to_ruby_hash(row_content));
|
180
|
+
return GMatx::t_continue;
|
151
181
|
}
|
152
182
|
|
153
183
|
static VALUE t_all(VALUE self)
|
@@ -160,10 +190,11 @@ static VALUE t_all(VALUE self)
|
|
160
190
|
return ret_hash;
|
161
191
|
}
|
162
192
|
|
163
|
-
static
|
193
|
+
static bool callback_func__ids(const std::string& key, const t_key_value_hash& row_content, void* args)
|
164
194
|
{
|
165
195
|
VALUE* p_ret_array = (VALUE*)(args);
|
166
196
|
rb_ary_push(*p_ret_array, rb_str_new_cstr(key.c_str()));
|
197
|
+
return GMatx::t_continue;
|
167
198
|
}
|
168
199
|
|
169
200
|
static VALUE t_ids(VALUE self)
|
@@ -207,6 +238,21 @@ static VALUE t_size(VALUE self)
|
|
207
238
|
return INT2NUM(pMatx->size());
|
208
239
|
}
|
209
240
|
|
241
|
+
static VALUE t_first(VALUE self)
|
242
|
+
{
|
243
|
+
class GMatx* pMatx = NULL;
|
244
|
+
Data_Get_Struct(self, class GMatx, pMatx);
|
245
|
+
|
246
|
+
std::string id;
|
247
|
+
t_key_value_hash row_hash = pMatx->first(id);
|
248
|
+
if (id.empty())
|
249
|
+
return Qnil;
|
250
|
+
VALUE ret_array = rb_ary_new();
|
251
|
+
rb_ary_push(ret_array, rb_str_new_cstr(id.c_str()));
|
252
|
+
rb_ary_push(ret_array, MatxHashUtil::key_value_hash_to_ruby_hash(row_hash));
|
253
|
+
|
254
|
+
return ret_array;
|
255
|
+
}
|
210
256
|
|
211
257
|
VALUE cSMatrix;
|
212
258
|
|
@@ -220,7 +266,9 @@ extern "C" void Init_s_matrix()
|
|
220
266
|
rb_define_method(cSMatrix, "to_s", (VALUE(*)(ANYARGS))t_to_s, 0);
|
221
267
|
rb_define_method(cSMatrix, "add_row", (VALUE(*)(ANYARGS))t_add_row, 2);
|
222
268
|
rb_define_method(cSMatrix, "get_row", (VALUE(*)(ANYARGS))t_get_row, 1);
|
269
|
+
rb_define_method(cSMatrix, "find", (VALUE(*)(ANYARGS))t_find, 1);
|
223
270
|
rb_define_method(cSMatrix, "each", (VALUE(*)(ANYARGS))t_each, 0);
|
271
|
+
rb_define_method(cSMatrix, "first", (VALUE(*)(ANYARGS))t_first, 0);
|
224
272
|
rb_define_method(cSMatrix, "all", (VALUE(*)(ANYARGS))t_all, 0);
|
225
273
|
rb_define_method(cSMatrix, "ids", (VALUE(*)(ANYARGS))t_ids, 0);
|
226
274
|
rb_define_method(cSMatrix, "keys", (VALUE(*)(ANYARGS))t_keys, 0);
|
data/lib/s_matrix/version.rb
CHANGED
data/spec/smatrix_spec.rb
CHANGED
@@ -102,16 +102,19 @@ describe SMatrix do
|
|
102
102
|
expect(a.all).to eq({})
|
103
103
|
expect(a.ids).to eq([])
|
104
104
|
expect(a.keys).to eq([])
|
105
|
+
expect(a.first).to eq(nil)
|
105
106
|
|
106
107
|
a.add_row('2', {a: 2})
|
107
108
|
expect(a.all).to eq({'2' => {'a' => '2'}})
|
108
109
|
expect(a.ids).to eq(['2'])
|
109
110
|
expect(a.keys).to eq(['a'])
|
111
|
+
expect(a.first).to eq(['2', {'a' => '2'}])
|
110
112
|
|
111
113
|
a.add_row('2', {b: 3})
|
112
114
|
expect(a.all).to eq({'2' => {'a' => nil, 'b' => '3'}})
|
113
115
|
expect(a.ids).to eq(['2'])
|
114
116
|
expect(a.keys).to eq(['a', 'b'])
|
117
|
+
expect(a.first).to eq(['2', {'a' => nil, 'b' => '3'}])
|
115
118
|
|
116
119
|
a.add_row('3', {b: 3})
|
117
120
|
expect(a.all).to eq({
|
@@ -120,6 +123,29 @@ describe SMatrix do
|
|
120
123
|
})
|
121
124
|
expect(a.ids).to eq(['2', '3'])
|
122
125
|
expect(a.keys).to eq(['a', 'b'])
|
126
|
+
expect(a.first == ['2', {'a' => nil, 'b' => '3'}] || a.first == ['3', {'b' => '3'}]).to eq(true)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'find' do
|
131
|
+
it '' do
|
132
|
+
a = SMatrix.new
|
133
|
+
expect( a.find({a: '2'}) ).to eq nil
|
134
|
+
|
135
|
+
a.add_row('223', {a: 2})
|
136
|
+
expect( a.find({a: '2'}) ).to eq ['223', {'a' => '2'}]
|
137
|
+
|
138
|
+
a.add_row('224', {a: 3})
|
139
|
+
expect( a.find({a: '2'}) ).to eq ['223', {'a' => '2'}]
|
140
|
+
expect( a.find({a: '3'}) ).to eq ['224', {'a' => '3'}]
|
141
|
+
expect( a.find({a: '3', b: nil}) ).to eq ['224', {'a' => '3'}]
|
142
|
+
|
143
|
+
a.add_row('225', {a: 2, b: 3})
|
144
|
+
expect( a.find({a: '2'})[0] == '223' || a.find({a: '2'})[0] == '224' ).to eq true
|
145
|
+
expect( a.find({b: '3'}) ).to eq ['225', {'a' => '2', 'b' => '3'}]
|
146
|
+
expect( a.find({a: '2', b: '3'}) ).to eq ['225', {'a' => '2', 'b' => '3'}]
|
147
|
+
expect( a.find({a: '2', b: '1'}) ).to eq nil
|
148
|
+
expect( a.find({a: nil, b: '3'}) ).to eq nil
|
123
149
|
end
|
124
150
|
end
|
125
151
|
|
data/todolist.txt
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
todolist:
|
2
2
|
|
3
3
|
1. function with first priority:
|
4
|
-
-done all
|
5
|
-
-return
|
6
|
-
-done
|
7
|
-
|
8
|
-
|
9
|
-
-return ['name', 'hp']
|
10
|
-
first
|
4
|
+
-done all -return {'23423' => {'name' => 'haha', 'hp' => '23425'}, '234232' => {} }
|
5
|
+
-done ids -return ['233423', '234134']
|
6
|
+
-done keys -return ['name', 'hp']
|
7
|
+
-done first -return: ['23423', {'name' => 'haha', 'hp' => '23425'}]
|
8
|
+
|
11
9
|
empty?
|
12
10
|
include? {|k, v| k == '2323232'}
|
13
|
-
|
11
|
+
-done find name: 'haha', hp: '2342' -return ['234232', {'name' => 'haha', 'hp' => '23425'}]
|
12
|
+
find_all name: 'haha', hp: '2342' -return [['234232', {'name' => 'haha', 'hp' => '23425'}], [], ...]
|
14
13
|
select {|k, v| k == '2232'}
|
15
14
|
merge
|
16
15
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: s_matrix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zhangyuan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -102,6 +102,8 @@ files:
|
|
102
102
|
- ext/s_matrix/gmatx.h
|
103
103
|
- ext/s_matrix/matx_content.cpp
|
104
104
|
- ext/s_matrix/matx_content.h
|
105
|
+
- ext/s_matrix/matx_hash_util.cpp
|
106
|
+
- ext/s_matrix/matx_hash_util.h
|
105
107
|
- ext/s_matrix/matx_row.cpp
|
106
108
|
- ext/s_matrix/matx_row.h
|
107
109
|
- ext/s_matrix/matx_string.h
|