2011-01-05 6 views
37

Làm thế nào để bạn thêm một mục vào một mảng hiện có trong VBScript?Thêm mục vào mảng trong VBScript

Có VBScript tương đương với chức năng đẩy trong Javascript không?

ví dụ:

myArray có ba hạng mục, "Táo", "Cam", và "Chuối" và tôi muốn thêm "dưa hấu" vào cuối của mảng.

Trả lời

55

Mảng không phải là rất năng động trong VBScript. Bạn sẽ phải sử dụng câu lệnh ReDim Preserve để phát triển mảng hiện có để nó có thể chứa một mục thêm:

ReDim Preserve yourArray(UBound(yourArray) + 1) 
yourArray(UBound(yourArray)) = "Watermelons" 
+0

cảm ơn vì sự giúp đỡ! – Choy

+6

Hãy lưu ý rằng 'Redim Preserve' sao chép toàn bộ mảng mỗi khi bạn sử dụng nó. Nói cách khác nó có n ** 2 phức tạp trong ký hiệu big-O. – mgr326639

+0

@user, sao chép toàn bộ mảng có độ phức tạp tuyến tính ('O (n)'), không phải bậc hai ('O (n²)'). –

9

Có một vài cách khác nhau, chưa kể một COM tùy chỉnh hoặc đối tượng ActiveX

  1. ReDim Bảo tồn
  2. Đối tượng từ điển, có thể có các phím chuỗi và tìm kiếm chúng
  3. ArrayList .Net Framework Class, có nhiều phương pháp bao gồm: sắp xếp (chuyển tiếp, đảo ngược, tùy chỉnh), chèn, xóa, binarysearch, bằng, toArray, và toString

Với mã dưới đây, tôi thấy Redim Preserve nhanh nhất dưới đây 54000, từ điển là nhanh nhất 54.000-690,000, và mảng Danh sách là nhanh nhất trên 690000. Tôi có xu hướng sử dụng ArrayList để đẩy vì chuyển đổi sắp xếp và mảng.

user326639 cung cấp FastArray, nhanh hơn rất nhiều.

Từ điển hữu ích để tìm kiếm giá trị và trả về chỉ mục (ví dụ: tên trường) hoặc nhóm và tổng hợp (biểu đồ, nhóm và thêm, nhóm và nối chuỗi, nhóm và đẩy mảng phụ). Khi nhóm trên các phím, hãy đặt CompareMode cho trường hợp trong/độ nhạy và kiểm tra thuộc tính "tồn tại" trước khi "thêm" -ing.

Redim sẽ không tiết kiệm được nhiều thời gian cho một mảng, nhưng nó hữu ích cho từ điển của mảng.

'pushtest.vbs 
imax = 10000 
value = "Testvalue" 
s = imax & " of """ & value & """" 

t0 = timer 'ArrayList Method 
Set o = CreateObject("System.Collections.ArrayList") 
For i = 0 To imax 
    o.Add value 
Next 
s = s & "[AList " & FormatNumber(timer - t0, 3, -1) & "]" 
Set o = Nothing 

t0 = timer 'ReDim Preserve Method 
a = array() 
For i = 0 To imax 
    ReDim Preserve a(UBound(a) + 1) 
    a(UBound(a)) = value 
Next 
s = s & "[ReDim " & FormatNumber(timer - t0, 3, -1) & "]" 
Set a = Nothing 

t0 = timer 'Dictionary Method 
Set o = CreateObject("Scripting.Dictionary") 
For i = 0 To imax 
    o.Add i, value 
Next 
s = s & "[Dictionary " & FormatNumber(timer - t0, 3, -1) & "]" 
Set o = Nothing 

t0 = timer 'Standard array 
Redim a(imax) 
For i = 0 To imax 
    a(i) = value 
Next 
s = s & "[Array " & FormatNumber(timer - t0, 3, -1) & "]" & vbCRLF 
Set a = Nothing 

t0 = timer 'Fast array 
a = array() 
For i = 0 To imax 
ub = UBound(a) 
If i>ub Then ReDim Preserve a(Int((ub+10)*1.1)) 
a(i) = value 
Next 
ReDim Preserve a(i-1) 
s = s & "[FastArr " & FormatNumber(timer - t0, 3, -1) & "]" 
Set a = Nothing 

MsgBox s 

' 10000 of "Testvalue" [ArrayList 0.156][Redim 0.016][Dictionary 0.031][Array 0.016][FastArr 0.016] 
' 54000 of "Testvalue" [ArrayList 0.734][Redim 0.672][Dictionary 0.203][Array 0.063][FastArr 0.109] 
' 240000 of "Testvalue" [ArrayList 3.172][Redim 5.891][Dictionary 1.453][Array 0.203][FastArr 0.484] 
' 690000 of "Testvalue" [ArrayList 9.078][Redim 44.785][Dictionary 8.750][Array 0.609][FastArr 1.406] 
'1000000 of "Testvalue" [ArrayList 13.191][Redim 92.863][Dictionary 18.047][Array 0.859][FastArr 2.031] 
+3

Tôi khuyên bạn nên thêm đoạn mã sau: t0 = timer 'Mảng nhanh a = mảng() Cho i = 0 Để imax ub = UBound (a) Nếu i> ub Sau đó ReDim Bảo toàn (Int() ub + 10) * 1.1)) a (i) = giá trị Tiếp theo ReDim Bảo toàn (i-1) s = s & "[FastArr" & FormatNumber (hẹn giờ - t0, 3, -1) & "] " Đặt a = Không có gì – mgr326639

+0

Cảm ơn! Tôi không bao giờ có thể nghĩ ra rằng – Will

+0

@ mgr326639 Điều gì sẽ xảy ra với 'ReDim Preserve a (i-1)' cuối cùng? – sirdank

3

thay đổi nhẹ với FastArray với phần trên:

'pushtest.vbs 
imax = 10000000 
value = "Testvalue" 
s = imax & " of """ & value & """" 

t0 = timer 'Fast array 
a = array() 
ub = UBound(a) 
For i = 0 To imax 
If i>ub Then 
    ReDim Preserve a(Int((ub+10)*1.1)) 
    ub = UBound(a) 
End If 
a(i) = value 
Next 
ReDim Preserve a(i-1) 
s = s & "[FastArr " & FormatNumber(timer - t0, 3, -1) & "]" 

MsgBox s 

Không có điểm trong kiểm tra UBound(a) trong mỗi chu kỳ của vì nếu chúng ta biết chính xác khi nào nó thay đổi.

Tôi đã thay đổi nó để nó kiểm tra không UBound(a) ngay trước khi cho bắt đầu và sau đó chỉ mỗi khi ReDim được gọi

Trên máy tính của tôi phương pháp cũ mất 7,52 giây cho một imax 10 triệu.

Phương pháp mới mất 5.29 giây cho imax cũng là 10 triệu, nghĩa là hiệu suất tăng trên 20% (đối với 10 triệu lần thử, rõ ràng tỷ lệ phần trăm này có mối quan hệ trực tiếp với số lần thử)

0

loại này muộn nhưng dù sao và nó cũng có phần phức tạp

dim arrr 
    arr= array ("Apples", "Oranges", "Bananas") 
dim temp_var 
temp_var = join (arr , "||") ' some character which will not occur is regular strings 
if len(temp_var) > 0 then 
    temp_var = temp_var&"||Watermelons" 
end if 
arr = split(temp_var , "||") ' here you got new elemet in array ' 
for each x in arr 
response.write(x & "<br />") 
next' 

xem xét và cho tôi biết nếu điều này có thể làm việc hoặc ban đầu bạn lưu tất cả dữ liệu trong chuỗi và phân chia sau đó cho mảng

0

Không phải là câu trả lời hoặc tại sao 'tricky 'Là xấu:

>> a = Array(1) 
>> a = Split(Join(a, "||") & "||2", "||") 
>> WScript.Echo a(0) + a(1) 
>> 
12 
4

Đối với sao chép và dán của bạn dễ dàng

' add item to array 
Function AddItem(arr, val) 
    ReDim Preserve arr(UBound(arr) + 1) 
    arr(UBound(arr)) = val 
    AddItem = arr 
End Function 

Được sử dụng như vậy

a = Array() 
a = AddItem(a, 5) 
a = AddItem(a, "foo")