Estoy tratando de hacer una función para obtener el principio y el final de una parte de una cadena similar a un bloque de código , devolviendo el índice de caracteres correspondiente. Ejemplo:
abc [ //A0 - start def [ //B1 - start ghi [ //C2 - start jkl ] //D2 - end ] //E1 - end ] //F0 - endentonces una función getBlock recibiría la cadena y el índice de uno de los caracteres ("[" o "]") y devolvería el índice de su socio correspondiente:
var str = "abc [def [ghi [jkl]]]"; getBlock(str, 4); // returns 20 ("F0" in the example) getBlock(str, 9); // returns 19 ("E1") getBlock(str, 14); // returns 18 ("D2") getBlock(str, 20); // returns 4 ("A0") getBlock(str, 19); // returns 9 ("B1") getBlock(str, 18); // returns 14 ("C2")Este es mi intento funcional hasta ahora:
function getBlock(str) { console.log({ "start": Array.from(str.matchAll(/\[/g)).map(m => m.index), "end": Array.from(str.matchAll(/\]/g)).map(m => m.index) }) } getBlock("abc [def [ghi [jkl]]]")Devuelve dos matrices que contienen el índice de todos los caracteres de inicio y finalización, pero todavía no he podido encontrar una lógica para obtener sus socios individualmente, ¿alguna idea si eso es posible?
Ok, terminé creando una solución algo fea, pero parece funcionar como se esperaba:
function getBlock(str, i) { var blocks = Array.from(str.matchAll(/\[|]/g)).map(m => m.index); return blocks[(blocks.length-blocks.indexOf(i))-1]; } // must return 20 19 18 4 9 14 var str = "abc [def [ghi [jkl]]]"; console.log( getBlock(str, 4), getBlock(str, 9), getBlock(str, 14), getBlock(str, 20), getBlock(str, 19), getBlock(str, 18) );la lógica es muy simple, en lugar de devolver dos matrices, solo devuelve una:
[4, 9, 14, 18, 19, 20]a partir de ahí, solo necesita obtener los valores del "medio":
14 18 9 19 4 20y eso es.
Editar: funciona para el caso en que cada bloque tiene solo un bloque dentro, pero si hay dos bloques uno al lado del otro, no. Ejemplo donde falla:
var str = "abc [def] [ghi]"; getBlock(str, 10) // returns 8 instead of 14Edición 2 ( Solución ):
De acuerdo, esta debería ser la solución de JavaScript adecuada, inspirada en el comentario de @HereticMonkey sobre ¿Cómo encuentro la posición de paréntesis o llaves coincidentes en un texto determinado? , la única diferencia es que esta versión está en JavaScript y se ha modificado ligeramente para permitir índices de inicio y fin.
function getBlock(str, start) { var end = start; var counter = 1; while (counter > 0) { var direction = (symbol) => ((str[start] == symbol) ? 1 : -1); var char = str[end += direction("[")]; if (char == "[" || char == "]") { counter += direction(char) }; } return { "start": start, "end": end }; } var str = "abc [def [ijk]] [ghi]"; console.log( getBlock(str, 4), // {start: 4, end: 14} getBlock(str, 9), // {start: 9, end: 13} getBlock(str, 16) // {start: 16, end: 20} );