Не думайте, что вам нужно создавать функцию, которая вызывает .save (). Все, что вам нужно сделать перед сохранением модели, можно сделать с помощью .pre ()
. Если вы хотите проверить, создается ли модель или обновляется, сделайте для этого проверку. isNew ()
Чтобы создать список с нуля, используйте LINQ:
ids.Split(',').Select(i => int.Parse(i)).ToList();
Если у вас уже есть объект списка, опустите вызов ToList () и используйте AddRange:
myList.AddRange(ids.Split(',').Select(i => int.Parse(i)));
Если некоторые записи в строке могут не быть целыми числами, вы можете использовать TryParse:
int temp;
var myList = ids.Split(',')
.Select(s => new { P = int.TryParse(s, out temp), I = temp })
.Where(x => x.P)
.Select(x => x.I)
.ToList();
Последний (более медленный) метод, который позволяет избежать temps / TryParse, но пропускает недопустимые записи, - использовать Regex:
var myList = Regex.Matches(ids, "[0-9]+").Cast<Match>().SelectMany(m => m.Groups.Cast<Group>()).Select(g => int.Parse(g.Value));
Однако это может сработать, если одна из ваших записей выходит за пределы int (999999999999 ).
Это должно помочь:
myList.Split(',').Select(s => Convert.ToInt32(s)).ToList();
Если список может содержать другие данные помимо целых чисел, следует включить вызов TryParse
. См. Принятый ответ.
Использование Linq:
myList.AddRange(ids.Split(',').Select(s => int.Parse(s));
Или напрямую:
var myList = ids.Split(',').Select(s => int.Parse(s));
Кроме того, чтобы компилятор не генерировал явно (в значительной степени избыточную) лямбду, рассмотрите:
var myList = ids.Split(',').Select((Func<string, int>)int.Parse);
(Подсказка: микрооптимизация. )
Также есть TryParse
, который следует использовать вместо Parse
(только), если возможен недопустимый ввод и он должен обрабатываться без уведомления. Однако другие опубликовали решения с использованием TryParse
, поэтому я, конечно, не буду. Только учтите, что не следует дублировать расчет.
Чтобы соответствовать запросу с точки зрения характеристик производительности и поведения, он должен делать то же самое и не выходить за рамки регулярных выражений или не выполнять «TryParse»: -
ds.Split(',')
.Select( i => {
int value;
bool valid = int.TryParse(out value);
return new {valid, value}
})
.Where(r=>r.valid)
.Select(r=>r.value)
.ToList();
Но хотя это правильно, это довольно некрасиво: D
Заимствовано из подсказки в комментарии Джейсона: -
ds.Split(',')
.Select( i => {
int value;
bool valid = int.TryParse(out value);
return valid ? new int?( value) : null;
})
.Where(r=>r != null)
.Select(r=>r.Value)
.ToList();
Или
static class Convert
{
public static Int32? ConvertNullable(this string s)
{
int value;
bool valid = int.TryParse(out value);
return valid ? new int?( value) : null;
}
}
ds.Split(',')
.Select( s => Convert.ConvertNullable(s))
.Where(r=>r != null)
.Select(r=>r.Value)
.ToList();
Или включение TryParse
, как в вашем примере:
var res = ids.Split(',').Where(x => { int tmp; return int.TryParse(x, out tmp); }).Select(x => int.Parse(x)).ToList();
Здесь есть одна проблема: как мы будем работать со значениями, которые не являются целыми числами (предположим, мы получим некоторые, которые не являются целыми числами). Одна из идей может заключаться в том, чтобы просто использовать регулярное выражение:
^ -? [0-9] + $
Теперь мы могли бы объединить все это с (как показано в примере Конрада):
var myList = ids.Split(',').Where(s => Regex.IsMatch(s, "^-?[0-9]$")).Select(s => Convert.ToInt32(s)).ToList();
Это должно сделать работа.