JSFiddle - React, Tailwind, and code Playground

Proxy: python-like array slicing

by Csaba Hellinger

JavaScript

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;
    }

	const handler = {
    	get (arr, 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, /*'PARTS', index, ' - SINGLE RESULT',*/ '    ', 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);
                }
                let result = [];
                for (let i = start; start <= end ? i < end : i > end; i += step) {
                	result.push(array[i]);
                    
                    if (i < 0 || i > 10) { throw new Error('ABORT'); }  // TODO: remove
                }
                console.log(prop, /*' - PARTS', start, end, step, ' - RESULT',*/ '    ', result);
                return result;
            }            
            return Reflect.get(array, prop);
        }
    };
    return new Proxy(array, handler);
}

console.clear();

let myArr = pythonIndex([0,1,2,3,4,5,6,7,8,9])

myArr['-1'];		// 9
myArr['0:3'];		// [0,1,2]	
myArr['8:5:-1'];	//...