4

私が言えることから、LINQ とラムダ式が私の特定の問題を解決する方法です。私のオフィスでは、2 次元配列 [X の長さ][2 幅] に IM ログのリストがあり、誰が誰に IM を送信したかを確認できます。ただし、ログは 3 桁のユーザー ID で構成され、実際の名前ではありません。

arrIMLog[x][1]

したがって、ログ エントリは次のようになります arrIMLog[0][0] = 353 および arrIMLog[0][1] = 563 は、ユーザー 353 がユーザー 563 に IM を送信したことを意味します。ログを精査することで、誰が IM を送信したかを知りたいと考えています。

lstSuspects

例として、lstSuspects(1) = 353、lstSuspects(2) = 563 などです。新しい単純なリスト lstSuspectsContacted を作成して、lstSuspects の各ユーザーがどの固有の UserID に連絡したか (# of時間はまだ問題ではありません)。どうすればいいですか?

var lstSuspectsContacted = (from x in arrIMLog
                            join y in lstSuspects 
             on arrIMLog[0] or arrIMLog[1] equals lstSuspects // join criteria
             select new { arrIMLog[0] or arrIMLog[1]}).ToList();

私が抱えている問題は、lstSuspects と他の要素 [1] または [0] 内の arrIMLog との間に一致があったかどうかに応じて、配列内の [0] または [1] 要素のいずれかを選択したいということです。これを達成する方法がわかりません。

4

3 に答える 3

1

ここでは、ラムダ結合の使用について簡単に説明します。注: 接触ペアの各接触に 1 つずつ、2 つの結合を使用しました。私もこれが最も効率的な解決策になると思います。

int[][] log = new int[][] {new int[]{1,2},new int[]{2,1},new int[]{1,3},new int[]{2,3},new int[]{3,4},new int[]{4,1}};
List<Suspect> Suspects = new List<Suspect>(){new Suspect(){SuspectId =  1, Name = "Bob"},new Suspect(){SuspectId =  2, Name = "Frank"},new Suspect(){SuspectId =  3, Name = "Jimmy"},new Suspect(){SuspectId =  4, Name = "DrEvil"}};


                //order the contact pairs as  2 --> 1 is the same as 1 --> 2 
 var q = log.Select (x => x.OrderBy (o => o))
                // Put contact record into an object which we have an IComparable for
            .Select (s => new Contact(){A = s.ElementAt(0),B= s.ElementAt(1) })
                //Now eliminate the duplicates
            .Distinct(new ContactComparer()) 
                //get the Name for contact A
            .Join(Suspects, contactKey => contactKey.A, suspectKey => suspectKey.SuspectId,(c,s) => new Contact{A = c.A, AName = s.Name, B = c.B})
                //get the Name for contact B
            .Join(Suspects, contactKey => contactKey.B, suspectKey => suspectKey.SuspectId,(c,s) => new Contact{A = c.A, AName = c.AName, B = c.B, BName = s.Name}) 
            .ToList();



//Classes that were used:

public class Contact
{

    public int A { get; set; }
    public String AName { get; set; }
    public int B { get; set; }
    public String BName { get; set; }

}

public class Suspect
{
    public int SuspectId { get; set; }
    public String Name { get; set; }
}



//We will use this in the .Distinct() linq method, to find the (and remove) the duplicates  
public class ContactComparer : IEqualityComparer<Contact>
{        
    public bool Equals(Contact x, Contact y)
    {

        //Check whether the compared objects reference the same data. 
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null. 
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the id fields are equal. 
        return x.A == y.A && x.B == y.B;
    }

      public int GetHashCode(Contact contact)
    {
        //Check whether the object is null 
        if (Object.ReferenceEquals(contact, null)) return 0;

        //Get hash code for the Name field if it is not null. 
        long contactA = contact.A == null ? 0 : contact.A;
        long contactB = contact.B == null ? 0 : contact.A;      

        //Calculate the hash code for the product. 
        return (int)((contactA + contactB) % int.MaxValue);
    }       

}

結果:

結果

于 2013-10-21T03:14:00.080 に答える
1

これは、より冗長に見えるかもしれませんが、より拡張可能で読みやすいソリューションです

ログを定義することから始めて、POCO を疑います。

    public class Log
    {
        /// <summary>
        /// Person initiating the contact
        /// </summary>
        public int From { get; set; }

        /// <summary>
        /// Person that was contacted
        /// </summary>
        public int To { get; set; }
    }

    public class SuspectConnection
    {
        public int SuspectId { get; set; }

        public List<int> Contacts { get; set; }
    }

その後、LINQ を使用して簡単に接続を見つけることができます。

    var suspectConnections = new List<SuspectConnection>();

    foreach (var suspect in suspects)
    {
        var connection = new SuspectConnection() { SuspectId = suspect };

        connection.Contacts = logs.Where(x => x.From == suspect || x.To == suspect).Select(x => x.From == suspect ? x.To : x.From).ToList();
        suspectConnections.Add(connection);
    }
于 2013-10-21T00:29:05.750 に答える