0
votes

Trouvez des éléments consécutifs dans la liste qui correspond à l'expression correspondante

Je voudrais récupérer les éléments d'une liste qui (dans une commande consécutive) correspond à une expression, mais pour le moment, je ne vois pas la solution (performante).

par exemple: p>

var items = new List<string>
{
   "1",
   ".",
   "249",
   "something",
   "1", // 5
   ".", // 6
   "250", // 7
   "yes"
};

// I am looking for the consecutive elements that form the expression below (5-6-7).
var match = "1.250";
var elements = ...;


8 commentaires

Les pièces sont-elles toujours séparées de la même manière?


Le poste pourrait-il inclure le code qui a été essayé?


En outre, dans l'exemple donné, recherchez-vous des "5,6,7" ou "4,5,6" (1 à base de comptage basé sur VS 0)?


@ elmer007 En effet, si vous célébrez 0,5,6, c'est pourquoi j'ai ajouté les commentaires 5-6-7 pour être assuré que tout le monde serait aligné. :-)


@juhararr Non, ils ne sont pas toujours séparés de la même manière. Pourrait être que le 250 serait divisé sur plusieurs enregistrements ou que vous auriez même 1 élément de la liste pour 1.250


Et si la chaîne de recherche est une sous-chaîne de l'une des chaînes de la liste? Comme si vous avez "1.250 quelque chose" dans la liste et que vous recherchez "1.250".


@juharr, j'aurais alors besoin de trouver l'élément de la liste qui dit "1,250 quelque chose".


@Jules bien aucune des réponses ici gère ce cas. Ils supposent tous que la valeur de recherche est exactement la même que celle d'un ensemble des chaînes de liste concaténées ensemble.


4 Réponses :


2
votes

Voici une façon qui est simple et n'est pas imbriquée plus de 1 niveau.

Cela trouvera le premier match. Si aucune correspondance n'est trouvée, index aura un nombre de 0 après la boucle. Mettez à l'intérieur d'une méthode de votre choix. xxx

avec une liste de 10 000 éléments, où les éléments à trouver sont à la fin, cela fonctionne environ 0,0003775 secondes.


2 commentaires

Merci! Très belle solution. J'ai toujours ajouté une chèque dans la boucle tandis que vous assurer que l'index ne sort pas de portée.


Ça a du sens. J'ai été édité pour inclure cette condition maintenant.



1
votes

Cela devrait donner une réponse, mais s'il y a plus d'un match, il renvoie le dernier. XXX


0 commentaires

0
votes
  public IEnumerable<int> GetMatch(List<string> items, string match)
  {
     string str = null;
     for (int i = 0; i < items.Count; i++)
     {
        if (!match.StartsWith(items[i]))
           continue;
        for (int j = 1; j < items.Count - i + 1; j++)
        {
           str = items.Skip(i).Take(j).Aggregate((x, y) => x + y);
           if (str.Equals(match))
              return Enumerable.Range(i + 1, j).Select(x => x).ToList();
           else if (match.StartsWith(str))
              continue;
           break;
        }
     }
     return new int[0];
  }



  [Fact]
  public void Test()
  {
     var items = new List<string> { "1", ".", "249", "something", "1", ".", "250", "yes" };
     var match = "1.250";
     var matchingIndexes = GetMatch(items, match);
     Assert.True(matchingIndexes.Any());
     Assert.Equal(5, matchingIndexes.ElementAt(0));
     Assert.Equal(6, matchingIndexes.ElementAt(1));
     Assert.Equal(7, matchingIndexes.ElementAt(2));
  }

0 commentaires

0
votes

Essayez IEQUABLE:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ConsoleApplication137
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> ipAddresses = new List<string>() {
                "172.15.15.1",
                "172.15.15.2",
                "172.15.15.3",
                "172.15.15.4",
                "172.16.15.1",
                "172.17.15.1"
            };

            MatchIp matchIP = new MatchIp("172.15", "172.16");
            List<string> results = ipAddresses.Where(x => matchIP.Equals(x)).ToList();
        }
    }
    public class MatchIp : IEquatable<string>
    {
        int[] startAddress { get; set; }
        int[] endAddress { get; set; }
        int length { get; set; }

        public MatchIp(string startAddressStr, string endAddressStr)
        {
            startAddress = startAddressStr.Split(new char[] { '.' }).Select(x => int.Parse(x)).ToArray();
            endAddress = endAddressStr.Split(new char[] { '.' }).Select(x => int.Parse(x)).ToArray();
            length = Math.Min(startAddress.Count(), endAddress.Count());
        }

        public Boolean Equals(string ip)
        {
            Boolean results = true;

            try
            {
                int[] address = ip.Split(new char[] { '.' }).Select(x => int.Parse(x)).ToArray();
                if (address.Length == 4)
                {
                    for (int i = 0; i < length; i++)
                    {
                        if ((address[i] < startAddress[i]) || (address[i] > endAddress[i]))
                        {
                            results = false;
                            break;
                        }
                    }
                }
                else
                {
                    results = false;
                }
            }
            catch (Exception ex)
            {
                results = false;
            }

            return results;
        }
    }

}


0 commentaires