2 votes

Extraire les numéros d'index de la liste de chaînes

J'ai une liste de chaînes où chaque chaîne a un indice et j'ai besoin d'extraire l'indice de cette chaîne et de le mettre dans une List.

Voici un exemple de liste :

List values = new List();
values.Add("cohabitantGender");
values.Add("additionalDriver0LastName");
values.Add("additionalDriver0AgeWhenLicensed");
values.Add("vehicle0City");
values.Add("vehicle1City");
values.Add("vehicle2City");
values.Add("vehicle3City");

de cette liste, je dois extraire les indices des valeurs vehicleXCity. J'ai actuellement ce code :

public static List FormObjectIndexExtractor(List values, string prefix, string suffix)
{
    var selectedMatches = values.Where(v => v.StartsWith(prefix) && v.EndsWith(suffix)).Select(v=> v).ToList();
    var indexes = new List();
    foreach (var v in selectedMatches) indexes.Add(int.Parse(Regex.Match(v, @"\d+").Value));
    return indexes;
}

Et je l'utilise de cette manière :

List indexes = FormObjectIndexExtractor(values, "vehicle", "City");

Mais si j'ai une valeur comme vehicle4AnotherCity, le code ne fonctionnera pas correctement.

Est-ce que quelqu'un a une alternative à ce code qui pourrait aider ?

1voto

Giddy Naya Points 1

Voici une classe d'aide à l'extension au cas où vous avez une liste plus robuste et que vous avez besoin de plusieurs options d'exclusion

public class INumberList : List
{ 
    public List GetNumberList()
    {
        List numberList = new List();
        for (int i = 0; i < this.Count; i++)
        {
            numberList.Add(GetIntFromString(this[i]));
        }
        return numberList;
    } 
    public INumberList ExcludeIndex(string prefix, string suffix)
    {
        for (int i = 0; i < this.Count; i++)
        { 
            if (this[i].StartsWith(prefix) && this[i].EndsWith(suffix))
            {
                //remove non needed indexes
                this.RemoveAt(i);
            }
        }
        return this;
    }
    public static int GetIntFromString(String input)
    {
        // Replace everything that is no a digit.
        String inputCleaned = Regex.Replace(input, "[^0-9]", "");

        int value = 0;

        // Tries to parse the int, returns false on failure.
        if (int.TryParse(inputCleaned, out value))
        {
            // The result from parsing can be safely returned.
            return value;
        }

        return 0; // Or any other default value.
    }
}

Utilisez comme ceci :

INumberList values = new INumberList();
        values.Add("cohabitantGender");
        values.Add("additionalDriver0LastName");
        values.Add("additionalDriver0AgeWhenLicensed");
        values.Add("vehicle0City");
        values.Add("vehicle1City");
        values.Add("vehicle2City");
        values.Add("vehicle3City");
//Obtenez la liste d'index filtrée avec plusieurs options d'exclusion
List indexList = values.ExcludeIndex("cohabitantGender","")
                        .ExcludeIndex("additionalDriver","AgeWhenLicensed")
                        .GetNumberList(); 
//retournera [0,0,1,2,3]

0voto

Jeppe Stig Nielsen Points 17887

Voici une solution (utilisant des fonctionnalités récentes de C#) qui n'utilise pas Regex:

public static List FormObjectIndexExtractor(IEnumerable values, string prefix, string suffix)
{
  int? TryParseItem(string val)
  {
    if (val.Length <= prefix.Length + suffix.Length || !val.StartsWith(prefix) || !val.EndsWith(suffix))
      return null;

    var subStr = val.Substring(prefix.Length, val.Length - prefix.Length - suffix.Length);

    if (int.TryParse(subStr, out var number))
      return number;

    return null;
  }

  return values.Select(TryParseItem).Where(v => v.HasValue).Select(v => v.Value).ToList();
}

0voto

jcruz Points 2440

Essayer ceci :

public static List FormObjectIndexExtractor(List values, string prefix, string suffix)
{
    var s = "^" + prefix + @"(\d+)\.*?" + suffix + "$";
    return values
            .Where(v => Regex.Match(v, s).Success)
            .Select(v=> int.Parse(Regex.Match(v, s).Groups[1].Value))
            .ToList();
}

-1voto

Tim Rutter Points 1024

Cette version divise toutes les parties de la chaîne.

public static List FormObjectIndexExtractor(List values, string prefix, string suffix)
{
    List ret = new List();
    Regex r = new Regex("^([a-zA-Z]+)(\\d+)([a-zA-Z]+)$");
    foreach (var s in values)
    {
        var match = r.Match(s);
        if (match.Success)
        {
            if (match.Groups[1].ToString() == prefix && match.Groups[3].ToString() == suffix)
            {
                ret.Add(int.Parse(match.Groups[2].ToString()));
            }
        }
    }
    return ret;
}

ou alternativement:

public static List FormObjectIndexExtractor(List values, string prefix, string suffix)
{
    List ret = new List();
    Regex r = new Regex($"^{prefix}(\d+){suffix}$");
    foreach (var s in values)
    {
        var match = r.Match(s);
        if (match.Success)
        {
            ret.Add(int.Parse(match.Groups[1].ToString()));
        }
    }
    return ret;
}

-2voto

EylM Points 1231

Ceci est la version la plus générique.

  1. Correspondance de Regex:

    • commence par 'véhicule'
    • correspond à un nombre
    • se termine par 'ville'.
  2. Analyse et retour en tant que List

        var indexes = values.Where(a => Regex.IsMatch(a, @"^véhicule\d+Ville$")).
                              Select(k => int.Parse(Regex.Match(k, @"\d+").Value)).ToList();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X