Существует ли эквивалент классу Сканера в C# для строк?

Я начал бить это. Это было хорошо в течение прошлого года, тогда что-то происходит с вложением хранилища, я думаю. Возможно, усовершенствования, происходящие на заднем плане, которые вызывают проблемы (PaaS!). В качестве меры предосторожности я вручную удаляю прямой путь и удаляю таблицу, пока не смогу получить приличное объяснение того, что происходит, или не получу ответ от службы поддержки.

Используйте

dbutils.fs.rm("dbfs:/user/hive/warehouse/schema.db/XXXXX", true)

, будьте осторожны с этим, хотя! Неправильный путь, и это может быть трагично!

32
задан Dhanuka 14 June 2015 в 19:42
поделиться

6 ответов

Я собираюсь добавить это как отдельный ответ, потому что это довольно отлично от ответа, который я уже дал. Вот то, как Вы могли начать создавать свой собственный класс Сканера:

class Scanner : System.IO.StringReader
{
  string currentWord;

  public Scanner(string source) : base(source)
  {
     readNextWord();
  }

  private void readNextWord()
  {
     System.Text.StringBuilder sb = new StringBuilder();
     char nextChar;
     int next;
     do
     {
        next = this.Read();
        if (next < 0)
           break;
        nextChar = (char)next;
        if (char.IsWhiteSpace(nextChar))
           break;
        sb.Append(nextChar);
     } while (true);
     while((this.Peek() >= 0) && (char.IsWhiteSpace((char)this.Peek())))
        this.Read();
     if (sb.Length > 0)
        currentWord = sb.ToString();
     else
        currentWord = null;
  }

  public bool hasNextInt()
  {
     if (currentWord == null)
        return false;
     int dummy;
     return int.TryParse(currentWord, out dummy);
  }

  public int nextInt()
  {
     try
     {
        return int.Parse(currentWord);
     }
     finally
     {
        readNextWord();
     }
  }

  public bool hasNextDouble()
  {
     if (currentWord == null)
        return false;
     double dummy;
     return double.TryParse(currentWord, out dummy);
  }

  public double nextDouble()
  {
     try
     {
        return double.Parse(currentWord);
     }
     finally
     {
        readNextWord();
     }
  }

  public bool hasNext()
  {
     return currentWord != null;
  }
}
24
ответ дан 27 November 2019 в 21:07
поделиться

В то время как это не то же самое фундаментальное понятие, что Вы ищете, может быть сделан с этим лямбда-выражением:

string foo = "0 0 1 22 39 0 0 1 2 33 33";

int[] data = foo.Split(' ').Select(p => int.Parse(p)).ToArray();

То, что это делает, является первым Split string, использование пространства как разделитель. Select функция затем позволяет Вам указывать псевдоним для данного участника в массиве (который я называемый как'p'в этом примере), затем выполните операцию на том участнике для предоставления конечного результата. ToArray() вызов затем превращает этот абстрактный счетный класс в конкретный массив.

Таким образом в этом конце, это разделяет string, затем преобразовывает каждый элемент в int и заполняет int[] с получающимися значениями.

3
ответ дан 27 November 2019 в 21:07
поделиться

К моему знанию, существуют не создан в классах в платформе для того, чтобы сделать это. Вы имели бы к самокрутке.

Это не было бы слишком твердо. Хорошая версия C# могла бы реализовать IEnumerable, таким образом, Вы могли сказать:

var scanner = new Scanner<int>(yourString);
foreach(int n in scanner)
    ; // your code
3
ответ дан 27 November 2019 в 21:07
поделиться

Для получения максимально близким к синтаксису это будет работать, если Вы только будете интересоваться одним типом ("интервал" в примере):

static void Main(string[] args)
{
   if (args.Length == 0) { args = new string[] { "3", "43", "6" }; }
   IEnumerator<int> scanner = (from arg in args select int.Parse(arg)).GetEnumerator();
   while (scanner.MoveNext())
   {
      Console.Write("{0} ", scanner.Current);
   }            
}

Вот еще больше версии удара свиста, которая позволяет Вам получать доступ к любому типу, который поддерживается реализацией строки IConvertible:

static void Main(string[] args)
{
    if (args.Length == 0) { args = new string[] { "3", "43", "6" }; }
    var scanner = args.Select<string, Func<Type, Object>>((string s) => {
            return (Type t) =>
            ((IConvertible)s).ToType(t, System.Globalization.CultureInfo.InvariantCulture); 
        }).GetEnumerator();
    while (scanner.MoveNext())
    {
        Console.Write("{0} ", scanner.Current(typeof(int)));
    }            
}

Просто передайте другой тип "typeof" оператору в цикле с условием продолжения для выбора типа.

Они оба требуют последних версий C# и платформы.NET.

2
ответ дан 27 November 2019 в 21:07
поделиться

Вы могли использовать linq для выполнения этого как так:

string text = "0 0 1 22 39 0 0 1 2 33 33";
text.Where(i => char.IsNumber(i)).Write(); // do somthing usefull here...
1
ответ дан 27 November 2019 в 21:07
поделиться

Я сделал бы это в одной из пары путей в зависимости от того, являетесь ли 1) Вы последнюю платформу.NET с поддержкой LINQ и 2) Вы, что значения являются допустимыми целыми числами. Вот функция для демонстрации обоих:

  int[] ParseIntArray(string input, bool validateRequired)
  {
     if (validateRequired)
     {
        string[] split = input.Split();
        List<int> result = new List<int>(split.Length);
        int parsed;
        for (int inputIdx = 0; inputIdx < split.Length; inputIdx++)
        {
           if (int.TryParse(split[inputIdx], out parsed))
              result.Add(parsed);
        }
        return result.ToArray();
     }
     else
        return (from i in input.Split()
                select int.Parse(i)).ToArray();
  }

На основе комментариев в другом ответе (ответах) я предполагаю, что Вам нужна проверка. После чтения тех комментариев я думаю самая близкая вещь, которую Вы получите, интервал. TryParse и дважды. TryParse, который является своего рода комбинацией hasNextInt и nextInt (или комбинацией hasNextDouble и nextDouble).

0
ответ дан 27 November 2019 в 21:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: