String
a la méthode intégrée .split ()
mais Array
ne l'a pas. Pourquoi?
Le mieux que je puisse faire est:
['(', 'name:', 'John', 'Deer', ')', '(', 'name:', 'Jane', 'Doe', ')'] .split(/\(|\)/); // [['name:', 'John', 'Deer'], ['name:', 'Jane', 'Doe']]
Array.prototype.split = function(separator) { return this.toString().split(separator) .map(egg => egg.split(',') .filter(Boolean)) .filter(egg => egg.length); }
Y a-t-il une manière plus concise d'écrire ceci, ou plus efficace à faire pour le cas général ?
3 Réponses :
à quoi cela ressemble:
function GroupAt( separator, array ){ const regString = (separator).toString().replace(/^\/|\/g?i?$/g, '').replace(/\\/, "\\"); return (array) .join(',') .replace( new RegExp( "^"+regString+"\\,|\\,"+regString+"$", 'g' ), '') .replace( new RegExp( '(,?'+ regString +',?){1,}', 'g' ), regString) .split(regString) .map(str => str.split(',')) } const sample = ['(', 'name:', 'John', 'Deer', ')', '(', 'name:', 'Jane', 'Doe', ')']; console.log(GroupAt(/[\(\)]/g, sample)) console.log(GroupAt( /(\(|\)|John)/g, sample ))
ou
function GroupAt( separator, array ){ return (array) .join(',') .replace( separator, ',') .replace( /^\,{1,}|\,{1,}$/g, '') .split( /\,{2,}/ ) .map(str => str.split(',')) }; const sample = ['(', 'name:', 'John', 'Deer', ')', '(', 'name:', 'Jane', 'Doe', ')']; console.log(GroupAt(/[\(\)]/g, sample)) console.log(GroupAt( /(\(|\)|John)/g, sample ))
UPDATE 1 (shortend)
(['(', 'name:', 'John', 'Deer', ')', '(', 'name:', 'Jane', 'Doe', ')']) .join(',') .match(/\,?\(\,?(.*?)\,\)\,?/g) .map( str => str.replace(/\,?[\(\)]\,?/g, '').split(',') );
C'est utile pour mon cas d'exemple mais ce n'est pas une fonction qui fonctionne pour tous les cas en général. String.split
permet d'utiliser des séparateurs à plusieurs caractères, mais comment diviser un Array
fonctionnerait-il avec des séparateurs à plusieurs éléments?
depuis que vous l'avez demandé, j'ai ajouté la suite logique de l'exemple suggéré à transformer en fonction, mais je ne peux toujours pas placer la nécessité générale
de if, plutôt qu'un cas d'utilisation spécifique. Existe-t-il un bon exemple pour illustrer l'idée derrière la généralisation sur un tableau, certains éléments étant un séparateur? Voulez-vous dire que les éléments de séparation du tableau doivent correspondre à votre requête du début à la fin ou qu'une correspondance partielle doit être acceptée?
Êtes-vous sûr de ne pas essayer de créer un tokenizer?
En voici un naïf:
[ [ 'name:', 'John', 'Deer' ], [ 'name:', 'Jane', 'Doe' ] ]
La valeur résultante est:
XXX
Voici quelque chose que j'ai recherché pour vous: https://www.freecodecamp.org/news/how-to-build-a-math-expression-tokenizer-using-javascript-3638d4e5fbe9/ p>
Aussi, une citation de Jamie Zawinski:
Certaines personnes, confrontées à un problème, pensent "Je sais, je vais utiliser des expressions régulières". Maintenant, ils ont deux problèmes.
La conversion en chaîne est problématique. Les éléments doivent être testés comme des éléments et non lorsqu'ils sont combinés avec d'autres éléments. Considérez le tableau:
[ [ 'hello, world', '3 / 4' ], [ 0.7, '1,2,3' ] ] [ [ 'hello, world', '3 / 4', '/' ], [ '1,2,3' ] ] [ [ '3 / 4', '/', 0.7, '1,2,3' ] ] [ [ 'hello, world', '3 / 4', '/', 0.7, '1,2,3' ] ] []
Voici une solution qui n'utilise pas de conversion de chaîne, sauf lors de la comparaison d'un élément individuel. Prend également en charge les expressions régulières.
console.log([ 'hello, world', '3 / 4', '/', 0.7, '1,2,3' ].split('/')); console.log([ 'hello, world', '3 / 4', '/', 0.7, '1,2,3' ].split(0.7)); console.log([ 'hello, world', '3 / 4', '/', 0.7, '1,2,3' ].split(/^hello/)); console.log([ 'hello, world', '3 / 4', '/', 0.7, '1,2,3' ].split(/^hello$/)); console.log([ ].split(1));
Tests:
Array.prototype.split = function(sep) { return this.reduce((acc, v, i) => { if (v == sep || (sep.exec && sep.exec(v))) acc.push([]); else { if (i == 0) acc.push([]); acc[acc.length-1].push(v); } return acc; }, []); }
Résultat:
[ 'hello, world', '3 / 4', '/', 0.7, '1,2,3' ]
Si les tableaux avaient une méthode nommée
split
, je ne m'attendrais pas du tout à ce que cela fonctionne de cette façon. De plus, au lieu d'ajouter des méthodes aux éléments intégrés, il est préférable de créer simplement une fonction utilitaireComment pensez-vous que cela fonctionne? Le fractionnement d'une
String
aboutit à un tableau de chaînes, il me semble donc logique que le fractionnement d'unArray
aboutisse à un tableau de tableaux.Étant donné que les tableaux sont des collections de valeurs de type arbitraire, je m'attendrais à ce qu'il se comporte d'une manière indépendante du type de ces valeurs et ne les convertisse pas automatiquement en chaînes.Personnellement, je m'attendrais à une sorte de segmentation ou de partitionnement.
['bonjour, monde', '3/4', '/', 0.7, '1,2,3'] .split ('/')
retournerait? Pas ce à quoi on pourrait s'attendre. Je suis d'accord avec @AluanHaddad, le fractionnement doit correspondre à un élément, pas à une chaîne une fois le tableau converti en chaîne. Le résultat de mon exemple devrait être[['hello, world', '3/4'], [0.7, '1,2,3']]
@AustinFrance, c'est définitivement une possibilité intéressante. Cela semble encore trop spécifique à l'ajout d'un membre au tableau