Easy Quesion about Array
Posted: 12 Sep 2017, 15:35
Pid[1] := 1234
Pid[2] := 5678
How to delete array element by value? like this Pid.Remove(5678)
Pid[2] := 5678
How to delete array element by value? like this Pid.Remove(5678)
Let's help each other out
https://www.autohotkey.com/boards/
https://www.autohotkey.com/boards/viewtopic.php?f=76&t=36982
Code: Select all
Pid:=[]
Pid[1] := 1234
Pid[2] := 5678
removeValue(pid,5678)
msgbox % Pid[2]
removeValue(arr,val){
t:=[]
for k, v in arr
if (v==val)
t.push(k)
for k, v in t
arr.delete(v)
}
NoHelgef wrote:Maybe like this
Code: Select all
Pid := [123, 456, 789]
RemoveValue(pid, 456)
MsgBox, % Pid[1] . "`n" . Pid[2] . "`n" . Pid[3]
RemoveValue(arr, val) {
for k, v in arr
if (v = val)
Return arr, arr.Delete(k)
}
Code: Select all
q::
oPID := {1114:"",2224:""}
MsgBox, % oPID.HasKey(1114)
MsgBox, % oPID.HasKey(3334)
oPID[3334] := "" ;this adds the key to the array
oPID.Delete(2224)
vOutput := ""
for vKey, vValue in oPID
vOutput .= vKey " " vValue "`r`n"
oPID := ""
MsgBox, % vOutput
return
Code: Select all
q::
oPID := [1234,5678,1234,5678,1234,5678,1234,5678,1234,5678]
Loop, % vLen := oPID.Length()
{
if (oPID[vLen] = 5678)
oPID.RemoveAt(vLen)
vLen--
}
for vKey, vValue in oPID
vOutput .= vKey " " vValue "`r`n"
oPID := ""
MsgBox, % vOutput
return
Your code in function.jeeswg wrote:Linear array approach
Code: Select all
removeVal(arr,val){
Loop % vLen := arr.Length()
if (arr[vLen--] = val)
arr.RemoveAt(vLen+1)
}
1 and 2. There was no specification.jeeswg wrote:Note:
No, both namely delete keys, yours remove. That may be undesirable, if I expect to see other keys in their old places.jeeswg wrote:both teadrinker's and Helgef's functions clear rather than delete keys (which may be desirable)
Code: Select all
q::
oArray := Object(StrSplit("a,1,b,2,c,3,d,1,e,2,f,3,g,1,h,2,i,3", ",")*)
;list keys
vOutput := ""
for vKey, vValue in oArray
vOutput .= vKey " " vValue "`r`n"
MsgBox, % vOutput
;remove keys where the value is 2
oRemove := []
for vKey, vValue in oArray
if (vValue = 2)
oRemove.Push(vKey)
Loop, % vIndex := oRemove.Length()
oArray.Delete(oRemove[vIndex--])
;list keys
vOutput := ""
for vKey, vValue in oArray
vOutput .= vKey " " vValue "`r`n"
MsgBox, % vOutput
oArray := oRemove := ""
return
Niftyjeeswg wrote:This script records which keys to delete, then deletes them afterwards.
Code: Select all
oRemove := []
for vKey, vValue in oArray
if (vValue = 2)
oRemove.Push(vKey)
Loop, % vIndex := oRemove.Length()
oArray.Delete(oRemove[vIndex--])
Code: Select all
for vKey, vValue in oArray
if (vValue = 2)
oArray.Delete(vKey)
Noteadrinker wrote:jeeswg, this codeyou may fearlessly replace with this:Code: Select all
oRemove := [] for vKey, vValue in oArray if (vValue = 2) oRemove.Push(vKey) Loop, % vIndex := oRemove.Length() oArray.Delete(oRemove[vIndex--])
Code: Select all
for vKey, vValue in oArray if (vValue = 2) oArray.Delete(vKey)
Code: Select all
oArray := [1, 2, 1, 2, 1, 2]
;list keys
vOutput := ""
for vKey, vValue in oArray
vOutput .= vKey " " vValue "`r`n"
MsgBox, % vOutput
;remove keys where the value is 2
for vKey, vValue in oArray
if (vValue = 2)
oArray.Delete(vKey)
;list keys
vOutput := ""
for vKey, vValue in oArray
vOutput .= vKey " " vValue "`r`n"
MsgBox, % vOutput
oArray := oRemove := ""
return
Code: Select all
oArray := [2, 2, 2, 2, 2, 2]
Code: Select all
for vKey, vValue in oArray.Clone()
if (vValue = 2)
oArray.Delete(vKey)
teadrinker wrote:for me it's unexpected behavior.
It is not something unique for ahk. Easy to miss though, I sure have at times and probably will again.for loop remarks wrote:Existing key-value pairs may be modified during the loop, but inserting or removing keys may cause some items to be skipped or enumerated multiple times.
Nice and short I'd worry slightly about cloning large arrays, but probably you will not go through large arrays looking for values to delete Anyways, always fun to see all ideas. Cheers.teadrinker wrote: Then this way:Code: Select all
for vKey, vValue in oArray.Clone() if (vValue = 2) oArray.Delete(vKey)
Thanks, I'll try to keep it on mind. Cheers.Helgef wrote:for loop remarks wrote:Existing key-value pairs may be modified during the loop, but inserting or removing keys may cause some items to be skipped or enumerated multiple times.
Code: Select all
q:: ;benchmark tests: delete keys from object forwards/backwards
vOutput := ""
vNum := 200000
oArray := {}
Loop, % vNum
oArray.Push("abcdefghij")
vTickCount1 := A_TickCount
Loop, % vIndex := oArray.Length()
oArray.Delete(oArray[vIndex--])
vTickCount2 := A_TickCount
vOutput .= (vTickCount2-vTickCount1) "`r`n"
oArray := {}
Loop, % vNum
oArray.Push("abcdefghij")
vTickCount1 := A_TickCount
Loop, % oArray.Length()
oArray.Delete(A_Index)
vTickCount2 := A_TickCount
vOutput .= (vTickCount2-vTickCount1) "`r`n"
oArray := ""
MsgBox, % vOutput
return
;100000 keys:
;47
;4430
;200000 keys:
;94
;20873
The array might contain huge strings. You will copy them and then discard them after the loop. It could be very wasteful.I can't remember what exactly the possible reasons against cloning were
It's really an interesting observation. Notice, that the codedeleting the last key has almost no cost, and deleting the first key has a big cost.
Code: Select all
oArray.Delete(oArray[vIndex--])
Code: Select all
oArray.Delete(vIndex--)
Code: Select all
SetBatchLines, -1
vNum := 100000
oArray1 := []
Loop, % vNum
oArray1.Push("abcdefghij")
oArray2 := oArray1.Clone()
start := A_TickCount
Loop % oArray1.Length()
if mod(key := vNum--, 2)
oArray1.Delete(key)
point1 := A_TickCount
Loop % oArray2.Length()
if mod(A_Index, 2)
oArray2.Delete(A_Index)
point2 := A_TickCount
MsgBox, % point1 - start "`n" point2 - point1