5

私のデータベースには次の 2 つの名前があります:SMITHSMITH1

名前がデータベースに存在する場合は、存在する場合にのみ 1 を追加SMITHし、番号付きの名前が既に存在する場合は、名前の数値部分を増やしたいと考えています。

1 つの LINQ ステートメントでこれを行うことは可能ですか? 今、私はやっています:

string name = string.Format("{0}{1}{2}",first_name,middle_name,last_name).ToUpper();

//Check for duplicates
while(names.SingleOrDefault (d => d.Name== name) != null)
{
    //Get last char
    char lastChar = name[name.Length - 1];

    //Last char is number
    if(Char.IsNumber(lastChar))
    {
        name = name.Replace(lastChar,Convert.ToChar(Convert.ToInt32(lastChar) + 1));
    }
    else
    {
        name = (name + 1);
    }
}

while ループに LINQ クエリがあるので、ループを繰り返す必要があるたびに選択を実行しますか?

また、これをより簡潔で読みやすいものにする方法を誰かが知っていれば、それは素晴らしいことでしょうか?

これは、数字がないか 1 ~ 9 の名前には機能しますが、10 になるとどうなりますか。最後の文字 (この場合は 0) のみが置き換えられます。これをどのように処理すればよいですか?

LINQ で数値部分を取得する方法はありますかSMITH12?12

4

5 に答える 5

0

これにより、次の名前が取得されます (たとえば、最新の増分が NAME10 の場合、次の名前は NAME11 になります)。

int tmp;
var existingNames = from name in names
                let numericIndex = name.IndexOfAny(new char[] {'1','2','3','4','5','6','7','8','9','0'}, 0)
                let subName = numericIndex > -1 ? name.Substring(0, numericIndex) : name
                let IndexAsString = numericIndex > -1 ? name.Substring(numericIndex) : "0"
                let index = int.TryParse(IndexAsString, out tmp) ? tmp : 0
                group new { subName, index } by subName into gs
                select gs;
var newNames = from existingName in existingNames
                select new { BaseName = existingName.Key, Index = existingName.Max(a => a.index) + 1 };
if (newNames.Any(a => a.BaseName == nameToAdd)) {
    // do your work to change the name
}
于 2013-05-13T16:02:20.440 に答える
0

このようなものを使用してください。

IEnumerable<string> existingNames = ...;

string rawName = ...;

string finalName = (from suffix in Enumerable.Range(0, int.MaxValue)
                    let testName = rawName + (suffix == 0 ? "" : suffix.ToString())
                    where existingNames.All(n => n != testName)
                    select testName).FirstOrDefault();

existingNamesごとに 1 回列挙されるメモsuffixexistingNamesの代わりにHashSet を使用することをお勧めしIEnumerable<string>ます。

HashSet<string> existingNames = ...;

string rawName = ...;

string finalName = (from suffix in Enumerable.Range(0, int.MaxValue)
                    let testName = rawName + (suffix == 0 ? "" : suffix.ToString())
                    where !existingNames.Contains(testName)
                    select testName).FirstOrDefault();
于 2013-05-13T15:52:01.800 に答える