0

i have the following scenario:

public class Term{
    private int _family;

    public void setFamily(int family){
         _family = family;
     }
    public int getFamily(){
        return _family
    }

}


public class Document{
     private List<Term> _terms_in_document;

     public void addTerm(Term t){
         _terms_in_document.add(t);
     }
}

in a different class...

   Term t1 = new Term();
   t1.setFamily(1);

   Term t2 = new Term();
   t2.setFamily(1);

   Term t3 = new Term();
   t3.setFamily(1);


   Document d1 = new Document();
    d1.addTerm(t1);
    d1.addTerm(t2);
    d1.addTerm(t3);

   Term t4 = new Term();
   t4.setFamily(1);

   Term t5 = new Term();
   t5.setFamily(2);

   Term t6 = new Term();
   t6.setFamily(3);


   Document d2 = new Document();
    d2.addTerm(t4);
    d2.addTerm(t5);
    d2.addTerm(t6);

I need to use LINQ to get those documents that contain terms with the biggest number of different families. In our example, d2 will come first because it's terms are of families 1, 2 and 3. While d1 has to come second because all of it's terms belong to the same family. I couldn't do this so far with linq, i believe it could be done without it, but it will be very complex and error prone code. Can you please help me..

J. Bend
  • 299
  • 2
  • 3
  • 14
  • 3
    Is your past experience in Java? Why are you not using an auto-property that'd generate a getter setter for you? Your whole family thing could be "public int Family {get; set;}" – Benjamin Gruenbaum Jan 12 '15 at 20:34
  • First off you need to expose the `Term` items you add to the `Document` class. Preferably by implementing `IEnumerable` if you want to use Linq – juharr Jan 12 '15 at 20:43

2 Answers2

1

You can use GroupBy to group the sequence of terms by family number, and then call Count on that to get the number of distinct groups.

Put all of that in an OrderByDescending call and you'll order the documents by the number of distinct families in all of their terms.

Servy
  • 202,030
  • 26
  • 332
  • 449
1

You should be using properties. This is what they're for. Also, to use LINQ, you'll need a collection of documents. In short your code can be converted to:

public class Term
{
    public int Family { get; set; }
}

public class Document
{
    private List<Term> terms = new List<Term>();
    public List<Term> Terms { get { return terms; } set { terms = value; } } 
}

internal class Program
{
    private static void Main(string[] args)
    {
        Term t1 = new Term { Family = 1 };  // Object Initializer Syntax
        Term t2 = new Term { Family = 1 };
        Term t3 = new Term { Family = 1 };

        Document d1 = new Document();
        d1.Terms.Add(t1);
        d1.Terms.Add(t2);
        d1.Terms.Add(t3);

        Term t4 = new Term { Family = 1 };
        Term t5 = new Term { Family = 2 };
        Term t6 = new Term { Family = 3 };

        Document d2 = new Document();
        d2.Terms.Add(t4);
        d2.Terms.Add(t5);
        d2.Terms.Add(t6);

        List<Document> docs = new List<Document> {d1, d2};
    }
}

then you can do your calculation with:

var mostDistinctFamilies = docs.GroupBy(d => d.Terms.Select(t => t.Family).Distinct().Count())
                               .OrderByDescending(d => d.Count())
                               .First();
Jonesopolis
  • 25,034
  • 12
  • 68
  • 112