Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

'Index was outside the bounds of the array.' Issue in LINQ Query From Array

Posted on 2010-08-18
30
Medium Priority
?
284 Views
Last Modified: 2013-11-11
I am getting an 'Index was outside the bounds of the array.' Error in Query2

Can you see why?


Dim Query1 = From n In str.Split(",")
            tmpNav.Append("<ul>" & vbCrLf)
            For Each n In Query1
                If ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5}) Then
                    Dim Query2 = From nl In n.ToString().Split("|") Where nl(1) = "0" And (nl(2) = "1" Or nl(2) = "2")
                    tmpNav.Append("<li class=""site_nav"">" & Query2.Count & "</li>" & vbCrLf)
                ElseIf Not (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5})) Then
                    Dim Query2 = From nl In n.ToString().Split("|") Where nl(1) = "0" And (nl(2) = "0" Or nl(2) = "2")
                    tmpNav.Append("<li class=""site_nav"">" & Query2.Count & "</li>" & vbCrLf)
                Else
                    Dim Query2 = From nl In n.ToString().Split("|") Where nl(1) = "0" And (nl(2) = "2")
                    tmpNav.Append("<li class=""site_nav"">" & Query2.Count & "</li>" & vbCrLf)
                End If
            Next
            tmpNav.Append("</ul>" & vbCrLf)

Open in new window

0
Comment
Question by:kevp75
[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
  • 17
  • 9
  • 4
30 Comments
 
LVL 25

Author Comment

by:kevp75
ID: 33468208
p.s.   There are 4 Items in n.ToString().Split("|")
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 33468500
Possibly a subscript issue? Arrays in VB.Net start at zero (unless you are intentionally checking the second and third elements!).

If that's not the issue could you post a sample of the data that might be in n?
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 33468517
p.s. nice to see you back on EE :o)
0
 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

 
LVL 25

Author Comment

by:kevp75
ID: 33468541
Hey carl :)

n = 178|0|2|Home,182|0|2|Sitemap,184|0|0|Login,185|0|0|Register,186|0|1|Logout,187|0|1|Profile,192|0|1|Change Password

New code...   (gets the 7 items in the comma-delimited list split)
Dim Query1 = From n In str.Split(",")
            tmpNav.Append("<ul>" & vbCrLf)
            For i As Integer = 0 To Query1.Count - 1
                If ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5}) Then
                    Dim Query2 = From nl In Query1.ToString().Split("|") Where nl(1) = "0" And (nl(2) = "1" Or nl(2) = "2")
                    tmpNav.Append("<li class=""site_nav"">" & Query2(0).ToString() & "</li>" & vbCrLf)
                ElseIf Not (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5})) Then
                    Dim Query2 = From nl In Query1.ToString().Split("|") Where nl(1) = "0" And (nl(2) = "0" Or nl(2) = "2") Select nl
                    tmpNav.Append("<li class=""site_nav"">" & Query2(0).Count & "</li>" & vbCrLf)
                Else
                    Dim Query2 = From nl In Query1(i).ToString().Split("|") Where nl(1) = "0" And (nl(2) = "2")
                    tmpNav.Append("<li class=""site_nav"">" & Query2(0).ToString() & "</li>" & vbCrLf)
                End If
            Next
            tmpNav.Append("</ul>" & vbCrLf)

Open in new window

0
 
LVL 25

Author Comment

by:kevp75
ID: 33468548
p.s.    Returns me Query2(0).Count = 0
0
 
LVL 25

Author Comment

by:kevp75
ID: 33468563
you can see it here:
http://indev.zipcm.com/
0
 
LVL 25

Author Comment

by:kevp75
ID: 33468602
I think I may have figured it out...


Dim Query2 = From nl In Query1 Let l = nl.Split("|") Where l(1) = "0" And (l(2) = "0" Or l(2) = "2") Select nl

Open in new window

0
 
LVL 25

Author Comment

by:kevp75
ID: 33468641
DOH...  spoke too soon
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 33468660
What is it that you are trying to get at?  Are you trying to pick out one piece of information from the string based on the values of the other elements?
0
 
LVL 23

Expert Comment

by:Snarf0001
ID: 33468711
Question, you have 2 different code segments posted here.

In the code in one of your responses "New code...   (gets the 7 items in the comma-delimited list split)"...
you have written
  Dim Query2 = From nl In Query1.ToString().Split("|")

That should be From nl in n.ToString()... not Query1.ToString(), otherwise you're going to be calling the split("|") on the .ToString() of Query1, which would be something like "System.Linq.IEnumberable....."
0
 
LVL 25

Author Comment

by:kevp75
ID: 33468770
Ok...  so when I do this:

                    For Each Item In Query2
                        tmpNav.Append("<li class=""site_nav"">" & Item(3) & "</li>" & vbCrLf)
                    Next

I get what is needed just multipled 7 times (due to the 7 items in n)

When I change it to:

                    'For Each Item In Query2
                    tmpNav.Append("<li class=""site_nav"">" & Query2(3).ToString & "</li>" & vbCrLf)
                    'Next


I get 7 System.String[]'s

???
0
 
LVL 25

Author Comment

by:kevp75
ID: 33468833
Essentially what I am trying to do is get a sites navigation from a comma delimited list.

Each Item in the comma delimited list is delimited with a |

So...  there are 7 items in the first interation, and 4 each thereafter


Dim Query1 = From n In str.Split(",")
            tmpNav.Append("<ul>" & vbCrLf)
            For i As Integer = 0 To Query1.Count - 1
                If ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5}) Then
                    Dim Query2 = From nl In Query1 Let l = nl.Split("|") Where nl(1) = "0" And (nl(2) = "1" Or nl(2) = "2") Select l
                    tmpNav.Append("<li class=""site_nav"">" & Query2.Count & "</li>" & vbCrLf)
                ElseIf Not (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5})) Then
                    Dim Query2 = From nl In Query1 Let l = nl.Split("|") Where l(1) = "0" And (l(2) = "0" Or l(2) = "2") Select l
                    'For Each Item In Query2
                    tmpNav.Append("<li class=""site_nav"">" & Query2.Count & "</li>" & vbCrLf)
                    'Next
                Else
                    Dim Query2 = From nl In Query1 Let l = nl.Split("|") Where nl(1) = "0" And (nl(2) = "2") Select l
                    tmpNav.Append("<li class=""site_nav"">" & Query2.Count & "</li>" & vbCrLf)
                End If
            Next
            tmpNav.Append("</ul>" & vbCrLf)

Open in new window

0
 
LVL 25

Author Comment

by:kevp75
ID: 33468849
Actually...  What I really should be doing is a Join on the first query, that way I always only get what I am after, instead of getting everything...

But, how would I do that  Select From One Split(",") Join another Split("|")
0
 
LVL 25

Author Comment

by:kevp75
ID: 33468901
the test data is:

178|0|2|Home,182|0|2|Sitemap,184|0|0|Login,185|0|0|Register,186|0|1|Logout,187|0|1|Profile,192|0|1|Change Password
0
 
LVL 23

Expert Comment

by:Snarf0001
ID: 33468916
Ok, and can you give a sample of the end <ul> you're trying to get this into?

0
 
LVL 25

Author Comment

by:kevp75
ID: 33468955
@Snarf0001   It's all in there...
0
 
LVL 23

Expert Comment

by:Snarf0001
ID: 33468970
No no, I mean I don't quite understand what you're trying to achieve, can you write out how you want the end result to look based on that sample data, ie:

<ul>
  <li class="samplecode">5</li>
</ul>

Or explain what each of the separated columns are supposed to represent.
0
 
LVL 25

Author Comment

by:kevp75
ID: 33469045
<ul>
<li class="site_nav">Link 1</li>
<li class="site_nav">Link 2</li>
<li class="site_nav">Link 3</li>
<li class="site_nav">Link 4</li>
<li class="site_nav">Link 5</li>
<li class="site_nav">Link 6</li>
<li class="site_nav">Link 7</li>
</ul>
0
 
LVL 23

Expert Comment

by:Snarf0001
ID: 33469147
Ok, IF I understand, it's the logic flow you're just a little bit off on.
Rather than trying to split everything on subsequent queries, you should be splitting BOTH parts off right off the start into a multidimensional array, so you can query the subparts (0, 1, 2, etc) in the further queries.

Not sure what the security checks shoudl be doing (as they're the same), but give this a shot:

        Dim str As String = "178|0|2|Home,182|0|2|Sitemap,184|0|0|Login,185|0|0|Register,186|0|1|Logout,187|0|1|Profile,192|0|1|Change Password"

        'get the full list into a multidimensional array that you can query the sub-parts of
        Dim itemArray = From n In str.Split(",") Select n.Split("|")

        tmpNav.Append("<ul>" & vbCrLf)
        If (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5}) Then
            'now make another query to filter the items on the sub-parts
            Dim q2 = From menuItem In itemArray Where menuItem(1) = "0" And (menuItem(2) = "1" Or menuItem(2) = "2")
            'and render out only the matched items
            For Each matchedItem In q2
                tmpNav.Append("<li class=""site_nav"">" & matchedItem(3) & "</li>" & vbCrLf)
            Next
        ElseIf Not (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5})) Then
            Dim q2 = From menuItem In itemArray Where menuItem(1) = "0" And (menuItem(2) = "0" Or menuItem(2) = "2")
            For Each matchedItem In q2
                tmpNav.Append("<li class=""site_nav"">" & matchedItem(3) & "</li>" & vbCrLf)
            Next
        Else
            Dim q2 = From menuItem In itemArray Where menuItem(1) = "0" And menuItem(2) = "2"
            For Each matchedItem In q2
                tmpNav.Append("<li class=""site_nav"">" & matchedItem(3) & "</li>" & vbCrLf)
            Next
        End If
        tmpNav.Append("</ul>" & vbCrLf)

Open in new window

0
 
LVL 25

Author Comment

by:kevp75
ID: 33469184
I'm wondering if a step could be skipped here....   how to filter that last Split?
0
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 33469223
Or something like:
            Dim Query1 = From n In Str.Split(",") Select n
            Dim Query2

            tmpNav.Append("<ul>" & vbCrLf)

            If ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5}) Then
                Query2 = (From nl In Query1
                                 Let n = nl.ToString().Split("|") Where n(1) = "0" And (n(2) = "1" Or n(2) = "2")
                                 Select n(3))
            ElseIf ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5}) Then
                Query2 = (From nl In Query1
                                 Let n = nl.ToString().Split("|") Where n(1) = "0" And (n(2) = "0" Or n(2) = "2")
                                 Select n(3))
            Else
                Query2 = (From nl In Query1
                             Let n = nl.ToString().Split("|") Where n(1) = "0" And n(2) = "1"
                             Select n(3))
            End If

            For Each result In Query2
                tmpNav.Append("<li class=""site_nav"">" & result.ToString() & "</li>" & vbCrLf)
            Next

            tmpNav.Append("</ul>" & vbCrLf)

Open in new window

0
 
LVL 23

Expert Comment

by:Snarf0001
ID: 33469348
Well, the 2nd split is the one that separates the data you're actually filtering on.  You're doing it in every conditional flow after that, so it makes more sense to do it up front.

But here would be a more optimized way of doing it:
        Dim str As String = "178|0|2|Home,182|0|2|Sitemap,184|0|0|Login,185|0|0|Register,186|0|1|Logout,187|0|1|Profile,192|0|1|Change Password"

        'get the full list into a multidimensional array that you can query the sub-parts of
        Dim itemArray = From n In str.Split(",") Select n.Split("|")
        'ALL paths you had were filtering off of the menuItem(1) = 0 as it was, so do it first
        Dim query = From menuItem In itemArray Where menuItem(1) = "0"

        If (tempval = True) Then
            query = query.Where(Function(menuItem) menuItem(2) = "1" Or menuItem(2) = "2")
        ElseIf Not tempval = True Then
            query = query.Where(Function(menuItem) menuItem(2) = "0" Or menuItem(2) = "2")
        Else
            query = query.Where(Function(menuItem) menuItem(2) = "2")
        End If

        tmpNav.Append("<ul>" & vbCrLf)
        For Each matchedItem In query
            tmpNav.Append("<li class=""site_nav"">" & matchedItem(3) & "</li>" & vbCrLf)
        Next
        tmpNav.Append("</ul>" & vbCrLf)

Open in new window

0
 
LVL 25

Author Comment

by:kevp75
ID: 33469353
tried something similar to that carl, but I kept getting 7x4 items displayed...

so far Snarf0001's seems to work, however, I would like to know if the 2 queries could be combined into one...

I imaginge that would be more efficient...
0
 
LVL 23

Accepted Solution

by:
Snarf0001 earned 2000 total points
ID: 33469367
Sorry on that last post, still had testing data in in place of the Zip.Security:
        Dim str As String = "178|0|2|Home,182|0|2|Sitemap,184|0|0|Login,185|0|0|Register,186|0|1|Logout,187|0|1|Profile,192|0|1|Change Password"

        'get the full list into a multidimensional array that you can query the sub-parts of
        Dim itemArray = From n In str.Split(",") Select n.Split("|")
        'ALL paths you had were filtering off of the menuItem(1) = 0 as it was, so do it first
        Dim query = From menuItem In itemArray Where menuItem(1) = "0"

        If (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5}) Then
            query = query.Where(Function(menuItem) menuItem(2) = "1" Or menuItem(2) = "2")
        ElseIf Not (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5})) Then
            query = query.Where(Function(menuItem) menuItem(2) = "0" Or menuItem(2) = "2")
        Else
            query = query.Where(Function(menuItem) menuItem(2) = "2")
        End If

        tmpNav.Append("<ul>" & vbCrLf)
        For Each matchedItem In query
            tmpNav.Append("<li class=""site_nav"">" & matchedItem(3) & "</li>" & vbCrLf)
        Next
        tmpNav.Append("</ul>" & vbCrLf)

Open in new window

0
 
LVL 23

Assisted Solution

by:Snarf0001
Snarf0001 earned 2000 total points
ID: 33469379
Keep in mind that since LINQ uses deferred execution, you can tack on where clauses at any point before the final execution, and the processor is still only going to query the data ONCE.
0
 
LVL 25

Author Comment

by:kevp75
ID: 33486416
do you think it would be faster if I use Linq to process this, or simply use the arrays I would get from Splitting the string and processing it that way?
0
 
LVL 23

Expert Comment

by:Snarf0001
ID: 33486435
Performance-wise doubt there would be any real difference.

From a programming perspective I far prefer the linq approach, it's much more consise and easy to read and follow than a series of ifs / switches and fors that would be required to do it the other way.
0
 
LVL 25

Author Comment

by:kevp75
ID: 33486750
Ok...  for some reason
                Return query.Count
                If (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5})) Then
                    query = query.Where(Function(menuItem) menuItem(2) = 1 Or menuItem(2) = 2)
                ElseIf Not (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5})) Then
                    query = query.Where(Function(menuItem) menuItem(2) = 0 Or menuItem(2) = 2)
                Else
                    query = query.Where(Function(menuItem) menuItem(2) = 2)
                End If

returns 7, but

                Dim query = From menuItem In itemArray Where menuItem(1) = 0
                If (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5})) Then
                    query = query.Where(Function(menuItem) menuItem(2) = 1 Or menuItem(2) = 2)
                ElseIf Not (ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5})) Then
                    query = query.Where(Function(menuItem) menuItem(2) = 0 Or menuItem(2) = 2)
                Else
                    query = query.Where(Function(menuItem) menuItem(2) = 2)
                End If
                Return query.Count

returns nothing....
0
 
LVL 23

Expert Comment

by:Snarf0001
ID: 33486871
Not sure why, given the test string you provided:
"178|0|2|Home,182|0|2|Sitemap,184|0|0|Login,185|0|0|Register,186|0|1|Logout,187|0|1|Profile,192|0|1|Change Password"

every path of the if statement returns items.
Please post more complete code, may be a problem somewhere else, and explain what the ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5}))  is supposed to do.
0
 
LVL 25

Author Comment

by:kevp75
ID: 33487079
ZipCM.Security.CanAccess(New Integer() {1, 2, 3, 4, 5})  returns a boolean value to determine whether a certain user type can access that particular part of the code.

i think that is where it'w at.....   it was working unil i switched some stuff...

thanks for the help
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

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

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…

604 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