2

I have a string array, and I need to get a range out of that, say 10 items counting from index 20.

I see there is an extension method called Take that can take a number of items from the beginning of the array, but I also need to specify the starting index.

5 Answers 5

8

Use the Skip method first. Like Take, it's a LINQ extension method and returns an IEnumerable:

Dim myRange = myArray.Skip(20).Take(10)

If the array contains 20 elements or less, the method does not throw an exception but returns an empty IEnumerable.

Sign up to request clarification or add additional context in comments.

Comments

2

You can use the Skip method to skip a number of items:

theArray.Skip(20).Take(10)

Comments

1

I wonder why the possibilities already in the BCL previous to Linq are "missing
For example using Array.Copy :

Dim copy(9) As String ' or Dim copy(0 To 9) As String ' hence 10 items
Array.Copy (source, 20, copy, 0, copy.Length)

Alternatively, if you want to have change in the initial array reflected in the copy (or you're sure it won't be modified) you can use an ArraySegment which is basicaly a "view" in the initial array and as such don't really involve a copy :

Dim view As New ArraySegment(Of String)(source, 20, 10)

Comments

0

Same example with Option Strict On

    Dim foo As IEnumerable(Of String) = myArray.Skip(20).Take(10)

    Dim arrayPart() As String = myArray.Skip(20).Take(10).ToArray

Comments

0

If you are stuck on .net 2.0 and want to have similar functionality without being able to monkey in LINQ, here is an implementation of similar array splicing. Probably could be tuned a bit faster but it should be flexible enough to handle any kind of array in vb.net:

Usage:

Dim a as New Integer(){0,1,2,3,4,5,6}
Dim a2 as Integer() = (New ArraySlicer(a)).skip(2).take(3).arr())
a2 = [2, 3, 4]

Code:

Public Class ArraySlicer
    Private _a as Object()
    Private _t as Type
    Private _l as Integer
    Public Sub New(ByVal o As Object, ByVal Optional t as Type = Nothing)
        if t is Nothing then
            Me._t = o.getType()
            if not Me._t.isArray then throw new Exception("Parameter o can only be an Array. Type passed is " & Me._t.FullName)
        else 
            Me._t = t
        end if
        Me._l = o.length
        Me._a = _copy(new Object(Me._l-1){}, o)
    End Sub

    Public Function skip(ByVal nskip as Integer) as ArraySlicer
        if nskip > Me._l then return new ArraySlicer(new Object(){}, Me._t)
        Dim a as Object() = new Object(Me._l - nskip - 1){}
        for i as Integer = nskip to Me._l - 1
            a(i - nskip) = Me._a(i)
        next
        return new ArraySlicer(a, Me._t)
    End Function

    Public Function take(ByVal ntake as Integer) as ArraySlicer
        if ntake > Me._l then return Me
        Dim a as Object() = new Object(ntake-1){}
        for i as Integer = 0 to ntake - 1
            a(i) = Me._a(i)
        next
        return new ArraySlicer(a, Me._t)
    End Function

    Private Function _copy(ByRef o1 as Object, o2 as Object)
        for i as Integer = 0 to Me._l - 1
            o1(i) = o2(i)
        next 
        return o1
    End Function

    Public Function arr() as Object
        Dim sT as String = Me._t.FullName
        if sT = "System.Int32[]" then
            return _copy(new Int32(Me._l-1){}, Me._a)

        elseif sT = "System.String[]" then
            return _copy(new String(Me._l-1){}, Me._a)

        elseif sT = "System.Boolean[]" then
            return _copy(new Boolean(Me._l-1){}, Me._a)

        elseif sT = "System.Byte[]" then
            return _copy(new Byte(Me._l-1){}, Me._a)

        elseif sT = "System.Char[]" then
            return _copy(new Char(Me._l-1){}, Me._a)

        elseif sT = "System.Decimal[]" then
            return _copy(new Decimal(Me._l-1){}, Me._a)

        elseif sT = "System.Double[]" then
            return _copy(new Double(Me._l-1){}, Me._a)

        elseif sT = "System.Int16[]" then
            return _copy(new Int16(Me._l-1){}, Me._a)

        elseif sT = "System.Int64[]" then
            return _copy(new Int64(Me._l-1){}, Me._a)

        elseif sT = "System.Single[]" then
            return _copy(new Single(Me._l-1){}, Me._a)

        elseif sT = "System.SByte[]" then
            return _copy(new SByte(Me._l-1){}, Me._a)

        elseif sT = "System.UInt16[]" then
            return _copy(new UInt16(Me._l-1){}, Me._a)

        elseif sT = "System.UInt32[]" then
            return _copy(new UInt32(Me._l-1){}, Me._a)

        elseif sT = "System.UInt64[]" then
            return _copy(new UInt64(Me._l-1){}, Me._a)

        elseif sT = "System.Object[]" then
            return _copy(new Object(Me._l-1){}, Me._a)

        else
            return Me._a
        end if
    end Function

end class

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.