Найти последовательные элементы в списке, которые соответствуют выражению - PullRequest
0 голосов
/ 23 октября 2019

Я хотел бы получить элементы из списка, которые (в последовательном порядке) соответствуют выражению, но на данный момент я не вижу решения (исполнителя).

Например:

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 = ...;

Ответы [ 4 ]

2 голосов
/ 23 октября 2019

Это простой и не вложенный более 1 уровня способ.

Здесь будет найдено первое совпадение. Если совпадений не найдено, indexes будет иметь счет 0 после цикла. Поместите в метод по вашему выбору.

List<int> indexes = new List<int>();
for (int i = 0; i < items.Count; i++)
{
    string temp = items[i];
    while (temp.Length < match.Length && temp == match.Substring(0, temp.Length) && i < items.Count - 1)
    {
        indexes.Add(i + 1); // example was given using 1-based
        temp += items[++i];
    }

    if (temp == match)
    {
        indexes.Add(i + 1);
        break; // at this point, indexes contains the values sought
    }

    indexes.Clear();
}

Со списком из 10000 элементов, где элементы для поиска находятся в конце, это выполняется примерно за 0,0003775 секунд.

1 голос
/ 23 октября 2019

Это должно дать ответ, но если найдено более одного совпадения, возвращается последнее.

 public static void GetConsecutiveMatch(List<String> items, String match, out List<int> indices)
    {
        indices = new List<int>();
        for (int i = 0; i < items.Count(); i++)
        {
            var strToCompare = "";
            for (int j = i ;  j < items.Count(); j++)
            {
                strToCompare += items[j];
                if (strToCompare.Length == match.Length)
                {
                    if (strToCompare == match)
                    {
                        indices.Clear();
                        for (int k = i; k <= j; k++)
                        {
                            indices.Add(k + 1); // at your example indices seems to be starting at 1, so I added 1 to the actual index
                        }
                    }

                    break;              
                }
                else if (strToCompare.Length > match.Length)
                {
                    break;
                }
            }
        }
    }
0 голосов
/ 23 октября 2019

Попробуйте IEquatable:

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 голосов
/ 23 октября 2019
  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));
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...