-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy path10-python-slicing.js
68 lines (59 loc) · 2.06 KB
/
10-python-slicing.js
1
2
3
4
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// 10 - Python-like array slicing
function pythonIndex(array) {
function parse(value, defaultValue, resolveNegative) {
if (value === undefined || isNaN(value)) {
value = defaultValue;
} else if (resolveNegative && value < 0) {
value += array.length;
}
return value;
}
function slice(prop) {
if (typeof prop === 'string' && prop.match(/^[+-\d:]+$/)) {
// no ':', return a single item
if (prop.indexOf(':') === -1) {
let index = parse(parseInt(prop, 10), 0, true);
console.log(prop, '\t\t', array[index]);
return array[index];
}
// otherwise: parse the slice string
let [start, end, step] = prop.split(':').map(part => parseInt(part, 10));
step = parse(step, 1, false);
if (step === 0) {
throw new RangeError('Step can\'t be zero');
}
if (step > 0) {
start = parse(start, 0, true);
end = parse(end, array.length, true);
} else {
start = parse(start, array.length - 1, true);
end = parse(end, -1, true);
}
// slicing
let result = [];
for (let i = start; start <= end ? i < end : i > end; i += step) {
result.push(array[i]);
}
console.log(prop, '\t', JSON.stringify(result));
return result;
}
}
const handler = {
get (arr, prop) {
return slice(prop) || Reflect.get(array, prop);
}
};
return new Proxy(array, handler);
}
// try it out
let values = [0,1,2,3,4,5,6,7,8,9],
pyValues = pythonIndex(values);
console.log(JSON.stringify(values));
pyValues['-1']; // 9
pyValues['0:3']; // [0,1,2]
pyValues['8:5:-1']; // [8,7,6]
pyValues['-8::-1']; // [2,1,0]
pyValues['::-1']; // [9,8,7,6,5,4,3,2,1,0]
pyValues['4::2']; // [4,6,8]
// and normal indexing still works
pyValues[3]; // 3