1

これは前の質問に関連していますが、個別に投稿するのに十分な違いがあるようです。

ユーザー入力(DomAttributeIdsおよびIntlAttributeIds)から文字列配列に格納される設定があります。条件付きで値の配列を作成して、コードを実行しようとしています。条件は次のとおりです。

  1. 存在する場合DomAttributesSettingsは、値の配列を作成し、それらをAddAttributeEdit()メソッドに渡します。
  2. 存在する場合IntlAttributesSettingsは、それらの設定の配列を作成し、条件1の設定と明確に(重複なしで)組み合わせて、その配列を残りのコードに渡し、最終的に各配列要素をAddAttributeEdit()メソッドに渡します。

以下のコードは、「重複なし」の部分を除いて機能しているようです。LinqのUnionおよび/またはDistinctメソッドを使用するとこれが可能になると思いましたが、何か間違ったことをしているに違いありません。私のコードは次の例外をスローします:

同じID'trAttribute_493'を持つ複数のコントロールが見つかりました。FindControlでは、コントロールに一意のIDが必要です。

これは、そのIDが両方の設定に存在するためです。最後のAddAttributeEdit()メソッドには、渡された値に基づいてIDを使用してテーブルとセルを作成するコードが含まれています。2つの配列の明確な結合を得るために私は何を間違っていますか?

コードは次のとおりです。

    private void LoadAttributes()
    {
        if (!string.IsNullOrEmpty(DomAttributesSetting))
        {
            string[] attributeIds;
            if (!string.IsNullOrEmpty(IntlAttributesSetting))
            {

                string[] domattributeIds = DomAttributesSetting.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                string[] intlattributeIds = IntlAttributesSetting.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                IEnumerable<string> atrributeIdList = domattributeIds.Union(intlattributeIds).Distinct();
                attributeIds = atrributeIdList.ToArray();
            }
            else
            {
                attributeIds = DomAttributesSetting.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            } 
            foreach (string attributeId in attributeIds)
            {
                int attrId = -1;
                if (int.TryParse(attributeId, out attrId) && attrId != -1)
                {
                    Arena.Core.Attribute attribute = new Arena.Core.Attribute(attrId);
                    PersonAttribute personAttribute = (PersonAttribute)person.Attributes.FindByID(attribute.AttributeId);
                    if (personAttribute == null)
                        personAttribute = new PersonAttribute(person.PersonID, attrId);

                    AddAttributeEdit(attribute, personAttribute, true);
                }

            }


        }

    }...
4

6 に答える 6

2

カンマ区切りリストの値の前後にパディングがあるか(「Prop1、Prop2」と「Prop1、Prop2」など)、大文字と小文字が異なります。

入力から各値をトリミングし、次のように大文字と小文字を区別しない比較ツールを使用してみてください。

var domattributeIds = DomAttributesSetting
    .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
    .Select(x=>x.Trim());

var intlattributeIds = IntlAttributesSetting
    .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
    .Select(x=>x.Trim());

var attributeIds = domattributeIds
    .Union(intlattributeIds, StringComparer.InvariantCultureIgnoreCase)
    .ToArray();

Distinct()最後に電話する必要すらありません。

于 2012-05-09T15:03:37.960 に答える
1

いくつかのintの異なる文字列表現が必要です。たとえば、先頭の「0」です。

最善の策は、int最初にsに変換してから、を実行することDistinctです。

何かのようなもの:

var ints = attributeIds.Select( s =>
{
  int i;
  return Int32.TryParse( s, out i ) ? i : -1;
};

var uniques = ints.Where( i => i != -1 ).Distinct().ToList();

foreach ( int attrId in uniques )
{
  Arena.Core.Attribute attribute = ...
于 2012-05-09T15:06:38.567 に答える
1

大文字と小文字だけが異なる2つの文字列がありますか?Linqは、デフォルトではそれらを重複として認識しません。代わりにこれを試してください:

domattributeIds.Union(intlattributeIds, StringComparer.CurrentCultureIgnoreCase)
于 2012-05-09T15:33:07.257 に答える
0
 string a = "a,b, c";
 string b = "b,c,d";
 String[] ass  = a.Split( new char[]{','}, StringSplitOptions.RemoveEmptyEntries);
 String[] bss =  b.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
 var list = ass.Union(bss).Distinct().ToArray();
 StringBuilder sb = new StringBuilder();
 foreach ( String s in list)
  {
    sb.Append(s);
  }
 Text = sb.ToString();

スペースがあるため、最終的なテキストは「abccd」です。入力にスペースが含まれていないことを確認してください

于 2012-05-09T15:03:54.573 に答える
0

LINQのUnionを使用します。例:

string[] domattributeIds = new string[] { "a", "b", "c" };
string[] intlattributeIds = new string[] { "a", "c", "d" };

string[] combined = domattributeIds.Union(intlattributeIds).ToArray();

新しい配列「combined」の値は「a」、「b」、「c」、「d」です。

于 2012-05-09T14:54:34.193 に答える
0

次のコードは、2つの文字列配列から個別の文字列配列を返します

public string[] UniqueNames(string[] names1, string[] names2) {
    newName = names1.ToList();
    foreach (var dr in names2) {
        if (!newName.Contains(dr)) {
            newName.Add(dr);
        }
    }
    string[] newNameArray = newName.ToArray();
    return newNameArray;
}

または、試してみることもできます

public string[] UniqueNames(string[] names1, string[] names2) {            
    return names1.Union(names2).ToArray(); ;            
}
于 2020-12-19T12:58:33.003 に答える