2010-06-28 6 views
0

J'ai une longue chaîne avec En-têtes et Sous-en-têtes. Chaque en-tête est censé avoir un sous-en-tête, mais pas le pré-traitement de la chaîne. J'ai besoin de le manipuler de telle sorte que chaque en-tête ait un sous-en-tête.javascript manipulation de chaînes

Chaque en-tête qui n'a pas de chaîne a un point de référence sous un en-tête différent. L'en-tête manquant le sous-en-tête doit saisir le sous-en-tête à partir de l'en-tête parent/en cours de la référence.

est ici à quoi il ressemble:

Header 1 
subheader - somedata A 
text 
reference-header-3 
stuff in the way 

Header 2 
subheader - somedata B 
stuff in the way 
stuff in the way 

Header 3 
stuff in the way 
stuff in the way 
reference-header-5 

Header 4 
subheader - somedata C 
some text 

Header 5 
more text 

je dois le faire pour ressembler à ceci:

Header 1 
subheader - somedata A 
text 
reference-header-3 
stuff in the way 

Header 2 
subheader - somedata B 
stuff in the way 
stuff in the way 

Header 3 
subheader - somedata A [this is copied from header 1] 
stuff in the way 
stuff in the way 
reference-header-5 

Header 4 
subheader - somedata C 
some text 

Header 5 
subheader - somedata A [this is copied from header 3] 
more text 

Si quelqu'un sait de toutes les bibliothèques de chaîne qui peuvent aider à faire ce qui serait génial . Je ne sais pas comment faire, je pense à les convertir en éléments DOM pour pouvoir les traverser avec jQuery, puis les reconvertir. Mais ça sonne un peu bizarre.

Quelqu'un sait-il comment faire?

Merci d'avance.

+0

N'utilisez pas jQuery pour cela. – SLaks

+0

Quelle est la taille des cordes? Peut-il y avoir des références vers l'avant? – SLaks

+0

@SLaks La chaîne est énorme. ~ 10 000 lignes. Je fais beaucoup d'autres choses dessus donc c'est assez lent. Mais ce n'est pas un problème pour cette application, la vitesse n'est pas nécessaire. Je pense que la substance 'reference-header-3' est une référence vers l'avant? (désolé si ce n'est pas ce que vous voulez dire.) Il est toujours vrai que chaque en-tête sans sous-en-tête a une référence en avant, donc il peut être préférable de faire défiler les références avant plutôt que chaque ligne. – Mark

Répondre

1

Si vous avez le contrôle du backend, ces données doivent être envoyées au format JSON. Ce serait le meilleur pari. Il est également relativement indolore. Vous ne devriez pas non plus utiliser jQuery pour cela (son utilisation n'est pas pertinente ici) sauf si vous utilisiez AJAX pour récupérer JSON comme je l'ai décrit.

Ou vous pouvez faire quelque chose comme ceci:

var str = "Header 1\none\ntwo\nthree\n\nHeader 2\nsubheader - one\ntwo\nthree\n\nHeader 3\none\ntwo\nthree\n"; 
var lines = str.split(/\n/); 

var headerMap = {}; 
var currentHeader = ""; 

for(var i = 0; i < lines.length; i++) { 

    var line = lines[i]; 
    line = line.replace(/^\s+/, "").replace(/\s+$/, ""); //trim whitespace 

    if(/^Header [0-9]+$/.test(line) && line != currentHeader) { 
     headerMap[line] = new Array(); 
     currentHeader = line; 
    } 

    //don't add blank lines 
    if(line != "") { 
     headerMap[currentHeader][headerMap[currentHeader].length] = line; 
    } 
} 

Maintenant vous avez une carte qui est calée par Header 1 et Header 2 et ainsi de suite. La valeur de chaque clé est un tableau contenant les différents sous-titres. Vous pouvez facilement itérer sur ces valeurs et vérifier la toute première valeur dans le tableau pour voir s'il a le préfixe subheader -. Sinon, vous pouvez l'ajouter.

Je viens de remarquer la deuxième partie. Je suppose que ce que vous pouvez faire après avoir fait ce qui précède est de faire une deuxième passe et d'analyser les parties reference et d'y insérer les valeurs appropriées. La solution de Slak pourrait être un one-pass je pense (de la lecture rapide je l'ai donné). OU vous pouvez ajouter un else-if au code ci-dessus (dans la boucle où il vérifie le hedaer) pour vérifier et voir s'il correspond à votre directive reference. Si c'est le cas, récupérez la référence existante et ajoutez-la (ce qui ne fonctionne que pour les références vers l'arrière). Si vous avez des références à suivre, vous devrez effectuer une deuxième passe.

0

Vous devez parcourir les lignes de la chaîne et créer une table de conversion en mappant les références d'en-tête à leurs champs de données et en ajoutant chaque ligne à un tableau output.

Lorsque vous rencontrez un en-tête, définissez un indicateur pour indiquer que vous attendez un sous-en-tête.
Si l'indicateur est défini et que la ligne actuelle n'est pas un sous-en-tête, recherchez la référence dans la table de recherche et ajoutez une ligne de sous-en-tête au tableau de sortie avant la ligne réelle.

Si la dernière ligne peut être un en-tête, vous devrez répéter cette vérification après la boucle.

Si la ligne de référence peut apparaître après l'en-tête, vous devrez vérifier & ajouter dans un second sous-en, en arrière, boucle à travers output après le remplissage output et remplissage de la table de consultation. Si c'est le cas, vous devez insérer les sous-titres en appelant le splice.

Lorsque vous avez terminé, appelez output.join('\n').

+0

Merci, cela a beaucoup de sens. J'y pense actuellement. S'il y a un code que vous pouvez partager, ce serait génial aussi. – Mark