【已解決】二維數據組依條件判斷刪除一行問題 (關於_ArrayDelete應用)
本帖最后由 kk_lee69 于 2011-6-22 13:34 编辑已知有一個二維數據組 資料 如下:
姓名 成績
張三 85
李四 51
王五 65
劉六 34
林七 98
本來用循環........然後去 判斷當 成績那邊的值<60 的時候就利用_ArrayDelete 刪除整行
問題是 一刪掉以後數據組的 整個結構就改變了......FOR 到最後會出問題.....況且判斷也會出問題
不知道是否 有更好的方法.....解決求助各位高手......謝謝 數據組的 整個結構----是什么意思,结构怎么会变 不好意思 我在這邊在補充一下說明.......
For $i=1 TO UBound($fArray)-1 Step 1
判斷 $fArray[$i] <60 的話就 _ArrayDelete 刪除那行.....
Next
所以當 $i=1得時候.....會把 那行刪除..... 這時候的陣列就會變成......
姓名 成績
張三 85
王五 65
劉六 34
林七 98
所以當 本來 $i=1所以刪除完畢後$=2這時王五就沒有比對了........
而且 程式跑到 $i=4 的時候也會出問題吧.........
補充說明....... 上面那個陣列 其實是從EXCEL 讀取出來的.......
重點是 想把 成績小於60的人刪除不要讀取到陣列裡面......
方法 一先讀取全部....在陣列裡面處理......這是我現在的想法遇到上面的問題
方法二 在EXCEL 裡面先處理好在讀取........ 可是 EXCEL的操作我不熟更困難 还是不明白,你是要删除元素后原来的索引不变吗?只删数据,不删数据位? 本帖最后由 happytc 于 2011-6-22 08:36 编辑
回复 3# kk_lee69
加个判断就可以了,其实这种最好用While..Wend或Do..Untile循环
因为For循环只是在第一次循环时读“步进值”和“ 停止值”,若你硬是要用For循环,也可以:
#include <Array.au3>
Local $Array = [["張三", 85], ["李四", 51], ["王五", 65], ["劉六", 34], ["林七", 98]]
Local $ArrSize
_ArrayDisplay($Array)
$ArrSize = UBound($Array) - 1
For $i = 0 To UBound($Array) - 1
If $i > $ArrSize Then ExitLoop
If $Array[$i] < 60 Then
_Array2DDelete($Array, $i)
$ArrSize -= 1
EndIf
Next
_ArrayDisplay($Array)
;----------------------------------------------------------------------------------------------------------------------
; Fuction _Array2DDelete(ByRef $ARRAY, $iDEL, $bCOL=False)
;
; Description Delete one row on a given index in an 1D/2D -Array
;
; Parameter $ARRAY the array, where one row will deleted
; $iDEL Row(Column)-Index to delete
; $bCOL If True, delete column instead of row (default False)
;
; Return Succes 0 ByRef $ARRAY
; Failure 1 set @error = 1; given array are not array
; set @error = 2; want delete column, but not 2D-array
; set @error = 3; index is out of range
;
;----------------------------------------------------------------------------------------------------------------------
Func _Array2DDelete(ByRef $ARRAY, $iDEL, $bCOL=False)
If ( Not IsArray($ARRAY) ) Then Return SetError(1,0,1)
Local $UBound2nd = UBound($ARRAY,2), $k
If $bCOL Then
If $UBound2nd = 0 Then Return SetError(2,0,1)
If ( $iDEL < 0 ) Or ( $iDEL > $UBound2nd-1 ) Then Return SetError(3,0,1)
Else
If ( $iDEL < 0 ) Or ( $iDEL > UBound($ARRAY)-1 ) Then Return SetError(3,0,1)
EndIf
If $UBound2nd = 0 Then
Local $arTmp
$k = 0
For $i = 0 To UBound($ARRAY)-1
If $i <> $iDEL Then
$arTmp[$k] = $ARRAY[$i]
$k += 1
EndIf
Next
Else
If $bCOL Then
Local $arTmp[$UBound2nd-1]
For $i = 0 To UBound($ARRAY)-1
$k = 0
For $l = 0 To $UBound2nd-1
If $l <> $iDEL Then
$arTmp[$i][$k] = $ARRAY[$i][$l]
$k += 1
EndIf
Next
Next
Else
Local $arTmp[$UBound2nd]
$k = 0
For $i = 0 To UBound($ARRAY)-1
If $i <> $iDEL Then
For $l = 0 To $UBound2nd-1
$arTmp[$k][$l] = $ARRAY[$i][$l]
Next
$k += 1
EndIf
Next
EndIf
EndIf
$ARRAY = $arTmp
Return 0
EndFunc ;==>_Array2DDelete
用_ArrayDelete()为
#include <Array.au3>
Local $Array = [["張三", 85], ["李四", 51], ["王五", 65], ["劉六", 34], ["林七", 98]]
Local $ArrSize
_ArrayDisplay($Array)
$ArrSize = UBound($Array) - 1
For $i = 0 To UBound($Array) - 1
If $i > $ArrSize Then ExitLoop
If $Array[$i] < 60 Then
_ArrayDelete($Array, $i)
$ArrSize -= 1
EndIf
Next
_ArrayDisplay($Array)
还是不明白,你是要删除元素后原来的索引不变吗?只删数据,不删数据位?
netegg 发表于 2011-6-22 04:25 http://www.autoitx.com/images/common/back.gif
回覆蛋蛋老大
我要刪除 數據以及 索引值.....但是 我用的語法....如同 Happytc 兄 所說的
因为For循环只是在第一次循环时读“步进值”和“ 停止值”,
所以在RUN 的時候會出問題........我想要解決的就是這個問題......如何讓程式可以完成判斷....又不會漏掉任何比對......刪除 不符合規則的數據以及索引值 回复 6# kk_lee69
1、前面只判断是否大于60,把小于60的序号保存至另外的数组,当所有数据跑完之后,倒序删除小于60的元素
2、这个方法数组比较大的话不建议使用,用新建数组承载大于60的原数组元素,不要进行del操作,因为AU对数组的支持确实差强人意,所以不用非得按着一条路子走到底
3、我一贯建议大家多想思路,而不是多记代码,这个对编程的思想很重要,另外最简单的代码是针对自己问题设计的代码,所有的UDF设计之初都考虑到了要适应所有的代码环境而使代码显得很臃肿,这不是UDF的错,而是用UDF的人懒 本帖最后由 3mile 于 2011-6-22 11:59 编辑
难道不能从尾序开始判断并删除?
#include <array.au3>
local $array
for $i=0 to 99
$array[$i]=ChrW(Random(19968,40869,1))&ChrW(Random(19968,40869,1))&ChrW(Random(19968,40869,1))
$array[$i]=Random(1,100,1)
Next
_ArrayDisplay($array)
$k=UBound($array)-1
for $i=UBound($array)-1 to 0 step -1
if $array[$i]<60 Then
_ArrayDelete($array,$i)
if $i<>$k Then $i+=1
EndIf
Next
_ArrayDisplay($array) 哈哈3mile老大的思路漂亮!!.........
今天我研究半天的結果也是這樣解決的.......
感謝 Happytc 兄 跟 3mile 的 範例....... 也感謝各位朋友的回覆....... 問題解決了!! 再請教3mile 老大 一個問題我看範例裡面有個
$k=UBound($array)-1 ====>看不懂用意的第一行
for $i=UBound($array)-1 to 0 step -1
if $array[$i]<60 Then
_ArrayDelete($array,$i)
if $i<>$k Then $i+=1 ====>看不懂用意的第二行
EndIf
Next
上述兩行的用意 看不太懂.............
為何....要設一個變數$K讓 $k=UBound($array)-1
然後又在循環裡面判斷if $i<>$k Then $i+=1
3mile 老大如果 用你的從後面開始判斷的邏輯來說......這兩行應該不需要吧 回复 10# kk_lee69
3mile也没有搞明白for循环时“起止变量”的内部用法
的确不需要那两行 Happytc 兄你的也有那兩行的用途.....但是是因為前提是要從 0到 尾端的方式 去做 fornext
目的是為了跳脫迴圈去做處理的吧 ...........我應該沒有理解錯誤吧
感謝提供技巧.......多學了一招 回复 11# happytc
你错了,仔细看. 本帖最后由 netegg 于 2011-6-22 20:31 编辑
回复 13# 3mile
三笑,这样是不是多算了一步,虽说影响不大,但如果100个成绩都小于60,岂不是要循环计算200次(我也没试可能想错了)
如果数组在删除后允许项目的索引变化,倒大可不必这么费事#include <Array.au3>
Dim $Array = [["張三", 85], ["李四", 51], ["王五", 65], ["劉六", 34], ["林七", 98]]
$index = _ArraySearch($Array, 60, 0, 0, 0, 0, 0, 1)
If @error Then
ReDim $Array
$Array = ''
$Array = 60
EndIf
_ArraySort($Array, 1,0,0,1)
$index = _Arrayfindall($Array, 60, 0, 0, 0, 0, 1)
ReDim $Array[$index-1]
_arraydisplay($Array, ' ')
排序后删掉后面的部分就可以了 我推翻刚才说的,建一个新的数组承载更好,因为本身del这个UDF就是数组重新排序,还不如直接重组的好
页:
[1]
2