Solved

LINQ help

Posted on 2014-10-03
10
147 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

 

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 34

Accepted Solution

by:
it_saige earned 500 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 34

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 34

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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
async questions 5 49
PowerShell:  foreach where object notmatch? 17 83
Example code 13 43
How to Rank results in SQL Server based on the search criteria 3 12
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

739 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