Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

LINQ help

Posted on 2014-10-03
10
Medium Priority
?
153 Views
Last Modified: 2016-02-15
Hi, I thought I understood LINQ.

I do not.

Below is some code I have written to try to get a distinct list of strings. It doesn't even compile. Can someone please help me get it right?

Thank you

John

using System;
using System.Linq;

namespace ConsoleApplication41
{
    public class Test0
    {
        public String[] Names { get; set; }
        public int id { get; set; }
    }

    public class Test1
    {
        public Test0[] Tests { get; set; }
        public int group { get; set; }
    }

    class Program
    {
        private void LinqTest()
        {
            Test0 test011 = new Test0 { Names = new String[] { "one", "two", "three" } };
            Test0 test012 = new Test0 { Names = new String[] { "three", "four" } };
            Test0 test013 = new Test0 { Names = new String[] { "ten", "one" } };
            Test1[] test1 = new Test1[] {new Test1 { Tests = new Test0[] { test011, test012, test013 } } };

            // Some magic LINQ to give me 
            // one, two, three, four, ten
            // from test1
            //
            // THE FOLLOWING DOESN'T WORKa
            var allTest1s = (
                                from y
                                    in (from x
                                           in test1
                                         select x.Tests
                                       )
                                select y.Names
                            ).ToArray<String>().Distinct<String>();
        }

        static void Main(string[] args)
        {
            Program program = new Program();
            program.LinqTest();
        }
    }
}

Open in new window

0
Comment
Question by:John Bolter
  • 4
  • 3
  • 3
10 Comments
 
LVL 22

Expert Comment

by:p_davis
ID: 40360285
what is the error/errors you are getting, when compiling.... seems x.Tests should be casted??
0
 

Author Comment

by:John Bolter
ID: 40360297
Hi, I struggled with that too.

I tried

            var allTest1s = (
                                from y
                                    in (from x
                                           in test1
                                         select ((Test0[])x.Tests)
                                       )
                                select y
                            ).ToArray<Test0>().Distinct<String>();

Open in new window


but then I couldn't convert all the Test0's to their Names Strings so I'm sort of missing an inner loop or something.
0
 
LVL 22

Expert Comment

by:p_davis
ID: 40360312
what errors are you getting?
0
Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

 

Author Comment

by:John Bolter
ID: 40360326
The error is it doesn't compile. This is what I think my LINQ query should look like but it is clearly wrong.

The compile error is

Error	1	Instance argument: cannot convert from 'System.Collections.Generic.IEnumerable<ConsoleApplication41.Test0[]>' to 'System.Collections.Generic.IEnumerable<ConsoleApplication41.Test0>'	c:\users\johneb\documents\visual studio 2013\Projects\ConsoleApplication41\ConsoleApplication41\Program.cs	39	30	ConsoleApplication41
Error	2	'System.Collections.Generic.IEnumerable<ConsoleApplication41.Test0[]>' does not contain a definition for 'ToArray' and the best extension method overload 'System.Linq.Enumerable.ToArray<TSource>(System.Collections.Generic.IEnumerable<TSource>)' has some invalid arguments	c:\users\johneb\documents\visual studio 2013\Projects\ConsoleApplication41\ConsoleApplication41\Program.cs	39	30	ConsoleApplication41

Open in new window

0
 
LVL 22

Expert Comment

by:p_davis
ID: 40360329
what happens if, in the select, you get rid of the cast (Test0[])
0
 

Author Comment

by:John Bolter
ID: 40360338
It still doesn't compile. I only added the cast because you suggested it above.

Try it. The whole program can be copy/pasted into Visual Studio
0
 
LVL 35

Accepted Solution

by:
it_saige earned 2000 total points
ID: 40360355
I think this is what you are after:
			var allTest1s = (from testGroup in test1
						  from test in testGroup.Tests
						  from name in test.Names
						  select name).Distinct();

Open in new window


-saige-
0
 
LVL 35

Expert Comment

by:it_saige
ID: 40360359
Using:
using System;
using System.Linq;

namespace LinqExample
{
	class Test0
	{
		public string[] Names { get; set; }
		public int Id { get; set; }
	}

	class Test1
	{
		public Test0[] Tests { get; set; }
		public int Group { get; set; }
	}

	class Program
	{
		static void Main(string[] args)
		{
			Test0 test011 = new Test0() { Names = new string[] { "one", "two", "three" } };
			Test0 test012 = new Test0() { Names = new string[] { "three", "four" } };
			Test0 test013 = new Test0() { Names = new string[] { "ten", "one" } };
			Test1[] test1 = new Test1[] { new Test1() { Tests = new Test0[] { test011, test012, test013 } } };

			var allTest1s = (from testGroup in test1
						  from test in testGroup.Tests
						  from name in test.Names
						  select name).Distinct();

			foreach (var test in allTest1s)
				Console.WriteLine(test);
			Console.ReadLine();
		}
	}
}

Open in new window

Produces the following output:Capture.JPG
-saige-
0
 

Author Closing Comment

by:John Bolter
ID: 40360361
I see how you've done it now, I didn't realise you could have two "from" like that. I was thinking in a sort of SQL way where that isn't a valid syntax.
Thank you
0
 
LVL 35

Expert Comment

by:it_saige
ID: 40360370
When you really think about it it makes sense.

test1 represents an array of Test1, so you enumerate over each Test1.
Inside of each Test1 you have an array of Test0's, represented as Tests, so you have to enumerate over each Test0.
Then inside of each Test0, you have an array of strings, represented as Names, so you have to enumerate over each Name.

-saige-
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This month, Experts Exchange sat down with resident SQL expert, Jim Horn, for an in-depth look into the makings of a successful career in SQL.
Hello there! As a developer I have modified and refactored the unit tests which was written by fellow developers in the past. On the course, I have gone through various misconceptions and technical challenges when it comes to implementation. I would…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …

877 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question