Крошечный способ получить первые 25 символов

Простой способ получить данные с сервера с помощью URLSession и рассмотреть следующий код:

var request = URLRequest(url: URL(string: "https://www.norsk-tipping.no/api-keno/getResultInfo.json?drawID=4178")!)
    request.httpMethod = "GET"
    let session = URLSession.shared

    session.dataTask(with: request) {data, response, err in
        print("Entered the completionHandler")

        if let data = data {
            do {
                let gameData = try JSONDecoder().decode(GameData.self, from: data)
                print(gameData)
            } catch {
                print(error)
            }
        }
}.resume()

И Codable struct будет выглядеть так:

import Foundation

struct GameData: Codable {
    let gameID, drawID: Int
    let drawDate: String
    let levels, wagers, correct, odds: [Int]
    let winners, drawNumbers, unsortedDrawNumbers: [Int]
    let turnover: Int
}

Выше struct вы можете анализировать данные.

Или вы можете просто использовать стороннюю библиотеку, такую ​​как Alamofire , для обработки запроса к серверу.

Но здесь важно то, что вы не получаете правильный JSON с сервера, где

while(true);/* 0;

и

/* */

не должно быть там.

Если вы попытаетесь вручную попытаться, удалив его, вы можете получить drawNumbers из этого, как показано ниже:

let data = """

{
"gameID": 13,
"drawID": 4178,
"drawDate": "2019,04,13,20,00,00",
"levels": [
10,
0,
0,
0,
0,
0,
0,
9,
0,
0,
0,
0,
0,
8,
0,
0,
0,
0,
7,
0,
0,
0,
6,
0,
0,
0,
5,
0,
0,
4,
0,
0,
3,
0,
2
],
"wagers": [
5,
10,
20,
30,
50,
100
],
"correct": [
10,
9,
8,
7,
6,
5,
0,
9,
8,
7,
6,
5,
0,
8,
7,
6,
5,
4,
7,
6,
5,
4,
6,
5,
4,
3,
5,
4,
3,
4,
3,
2,
3,
2,
2
],
"odds": [
200000,
5000,
200,
20,
4,
1,
1,
50000,
1100,
50,
8,
2,
1,
10000,
240,
20,
3,
1,
2400,
100,
10,
1,
420,
20,
3,
1,
200,
9,
1,
35,
2,
1,
18,
1,
7
],
"winners": [
0,
5,
27,
196,
959,
3308,
1556,
1,
0,
8,
56,
219,
294,
1,
3,
59,
305,
1043,
5,
10,
77,
386,
2,
58,
393,
1340,
16,
108,
548,
44,
433,
1682,
126,
971,
259
],
"drawNumbers": [
1,
13,
23,
30,
40,
42,
43,
48,
49,
50,
51,
52,
53,
54,
55,
56,
60,
61,
63,
65
],
"unsortedDrawNumbers": [
63,
52,
13,
56,
53,
30,
54,
23,
65,
55,
61,
1,
51,
42,
60,
43,
48,
49,
50,
40
],
"turnover": 795865
}

""".data(using: .utf8)!

    do {
        let gameData = try JSONDecoder().decode(GameData.self, from: data)
        print(gameData.drawNumbers) //[1, 13, 23, 30, 40, 42, 43, 48, 49, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 65]
    } catch {
        print(error)
    }

Вы можете попробовать приведенный выше код на игровой площадке.

10
задан Duke of Muppets 27 February 2009 в 14:34
поделиться

12 ответов

Мне было нужно это так часто, я записал дополнительный метод для него:

public static class StringExtensions
{
    public static string SafeSubstring(this string input, int startIndex, int length, string suffix)
    {
        // Todo: Check that startIndex + length does not cause an arithmetic overflow - not that this is likely, but still...
        if (input.Length >= (startIndex + length))
        {
            if (suffix == null) suffix = string.Empty;
            return input.Substring(startIndex, length) + suffix;
        }
        else
        {
            if (input.Length > startIndex)
            {
                return input.Substring(startIndex);
            }
            else
            {
                return string.Empty;
            }
        }
    }
}

если Вам только нужен он однажды, который является излишеством, но если Вам нужен он чаще затем, это может пригодиться.

Править: Добавленная поддержка строкового суффикса. Передача в "..." и Вы получаете свои замещающие знаки на более коротких строках или передачу в строке. Пустой ни для каких специальных суффиксов.

28
ответ дан 3 December 2019 в 13:12
поделиться
public static Take(this string s, int i)
{
    if(s.Length <= i)
        return s
    else
        return s.Substring(0, i) + "..."
}

public string ShortDescription
{
    get { return this.Description.Take(25); }
}
11
ответ дан 3 December 2019 в 13:12
поделиться
return this.Description.Substring(0, Math.Min(this.Description.Length, 25));

Не имеет ... часть. Ваш способ является, вероятно, лучшим на самом деле.

23
ответ дан 3 December 2019 в 13:12
поделиться

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

Вы действительно хотите сохранить это в своем бобе хотя? По-видимому, это для дисплея где-нибудь, таким образом, Ваш рендерер должен быть вещью, делающей усечение вместо объекта данных

6
ответ дан 3 December 2019 в 13:12
поделиться

Хорошо я знаю, что уже существует ответ, принятый, и я могу быть замучен для вывода регулярного выражения здесь, но это - то, как я обычно делаю это:

//may return more than 25 characters depending on where in the string 25 characters is at
public string ShortDescription(string val)
{
    return Regex.Replace(val, @"(.{25})[^\s]*.*","$1...");
}
// stricter version that only returns 25 characters, plus 3 for ...
public string ShortDescriptionStrict(string val)
{
    return Regex.Replace(val, @"(.{25}).*","$1...");
}

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

Оборотная сторона, хорошо я уверен, что это не возможное быстрое решение.

Править: замененный … с "..." с тех пор не уверенный, если это решение для сети!

4
ответ дан 3 December 2019 в 13:12
поделиться

без.... этого должно быть самым коротким:

public string ShortDescription
{
    get { return Microsoft.VisualBasic.Left(this.Description;}
}
3
ответ дан 3 December 2019 в 13:12
поделиться

Я думаю, что подход является звуковым, хотя я рекомендовал бы несколько корректировок

  • Переместите магическое число в a const или значение конфигурации
  • Используйте постоянного клиента if условное выражение, а не тернарный оператор
  • Используйте a string.Format("{0}...") вместо + "..."
  • Имейте всего одну точку возврата от функции

Так:

public string ShortDescription
{
    get
    {
        const int SHORT_DESCRIPTION_LENGTH = 25;

        string _shortDescription = Description;

        if (Description.Length > SHORT_DESCRIPTION_LENGTH)
        {
            _shortDescription = string.Format("{0}...", Description.Substring(0, SHORT_DESCRIPTION_LENGTH));
        }

        return _shortDescription;
    }
}

Для более общего подхода Вы хотели бы перемещать логику в дополнительный метод:

public static string ToTruncated(this string s, int truncateAt)
{
    string truncated = s;

    if (s.Length > truncateAt)
    {
        truncated = string.Format("{0}...", s.Substring(0, truncateAt));
    }

    return truncated;
}

Править

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

Edit2

Для типографской правильности Вы могли также рассмотреть использование символа замещающего знака (…) в противоположность трем точкам/периодам/точкам (...).

1
ответ дан 3 December 2019 в 13:12
поделиться

Один способ сделать это:

int length = Math.Min(Description.Length, 25);
return Description.Substring(0, length) + "...";

Существует две строки вместо одной, но более короткие :).

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

На данном этапе я думаю с помощью строковых расширений, единственная опция сократить код. И это имеет смысл только, когда тот код повторяется по крайней мере в нескольких местах...

1
ответ дан 3 December 2019 в 13:12
поделиться

Выглядит хорошо мне, будучи действительно придирчивым я заменил бы "..." ссылкой на сущность "&hellip;"

0
ответ дан 3 December 2019 в 13:12
поделиться

Я придерживался бы с тем, что у Вас есть tbh, но так же, как альтернатива, если у Вас есть LINQ к объектам, Вы могли

new string(this.Description.ToCharArray().Take(25).ToArray())

//And to maintain the ...
+ (this.Description.Length <= 25 ? String.Empty : "...")

Как другие сказали, Вы, вероятно, хотели бы сохранить 25 в константе

0
ответ дан 3 December 2019 в 13:12
поделиться

Я не могу думать ни о ком, но Ваш подход не мог бы быть лучшим. Вы добавляете логику представления в свой объект данных? Раз так затем я предполагаю, что Вы помещаете ту логику в другом месте, например, статический класс StringDisplayUtils с GetShortStringMethod (интервал maxCharsToDisplay, представьте stringToShorten в виде строки).

Однако тот подход не мог бы быть большим также. Что относительно различных шрифтов и наборов символов? Необходимо было бы начать измерять фактическую длину строки с точки зрения пикселей. Проверьте свойство AutoEllipsis на класс Маркировки winform (Вы будете, prob должен установить AutoSize на ложь при использовании этого). Свойство AutoEllipsis, когда верный, укоротит строку и добавит '...' символы для Вас.

0
ответ дан 3 December 2019 в 13:12
поделиться

Необходимо видеть, можно ли сослаться на Microsoft. VisualBasic DLL в Ваше приложение, таким образом, можно использовать "Левую" функцию.

0
ответ дан 3 December 2019 в 13:12
поделиться
Другие вопросы по тегам:

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