Sign in to follow this  
Followers 0
cherdeg

Simple ? Array Resort Problem

8 posts in this topic

#1 ·  Posted (edited)

Hi,

I'm somehow stuck: I've got to resort an array of at least the following five values:

"RDPNP", "npnotes", "LanmanWorkstation", "WebClient", "PssoCM32"

There are also situations where the array holds more elements. The values "npnotes" and "WebClient" may appear on any postition of the array. The resort has to conform to the following rules:

1.) After the resort no values must be lost or added; the number of values must stay the same.

2.) "npnotes" has to be the value following directly after "WebClient".

3.) "WebClient" should become element 3 or larger (if there are more than "RDPNP" and "LanmanWorkstation" before it).

4.) All other elements should keep their curent order.

I'm officially too dumb to solve this seemingly easy job - please help...

Best Regards,

Chris

Edit: Here my code so far - it just doesn't work perfekt.

; AutoIT-Includes
#include <Array.au3>

; General Variables
Global $r_key = "\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order"
Global $r_value = "ProviderOrder"
Global $s_source
Global $s_target
Global $a_Values
Global $i_Pos1
Global $i_Pos2
Global $i_RegWriteResult

; Main
; ==================================================================================================
If @OSArch == "X86" Then $r_key = "HKLM" &  $r_key
If @OSArch == "X64" Then $r_key = "HKLM64" &  $r_key

$s_source = RegRead($r_key, $r_value)
If $s_source = "" And @error <> 0 Then
    ConsoleWrite(@CRLF & "Something went terribly wrong while reading the key, so from now on fear the dark - " & $s_source & ": " & @error & @CRLF)
Else
    ; Backup the original Registry Value
    $i_RegWriteResult = RegWrite($r_key, $r_value & "_Backup", "REG_SZ", $s_source)
    If $i_RegWriteResult <> 1 Then
        ConsoleWrite(@CRLF & "Something went terribly wrong while writing the key, so from now on fear the dark - " & $s_source & ": " & @error & @CRLF)
    EndIf

    $a_Values = StringSplit($s_source, ",", 2)
    For $i_i = 0 To UBound($a_Values) - 1
        If $a_Values[$i_i] == "WebClient" Then $i_Pos1 = $i_i
        If $a_Values[$i_i] == "npnotes" Then $i_Pos2 = $i_i
    Next

    If $i_Pos2 <> $i_Pos1+1 Then

_ArrayDisplay($a_Values, "Before")
        If $i_Pos1 == 0 Then
            _ArrayInsert($a_Values, $i_Pos1+3, $a_Values[$i_Pos1])
            _ArrayDelete($a_Values, $i_Pos1)
            _ArrayInsert($a_Values, $i_Pos1+4, $a_Values[$i_Pos2])
            _ArrayDelete($a_Values, $i_Pos2+1)
_ArrayDisplay($a_Values, "After-0")
        ElseIf UBound($a_Values)-1 >= $i_Pos1+1 Then
            _ArrayInsert($a_Values, $i_Pos1+1, $a_Values[$i_Pos2])
            _ArrayDelete($a_Values, $i_Pos2)
_ArrayDisplay($a_Values, "After-1")
        ElseIf UBound($a_Values)-1 = $i_Pos1 Then
            _ArrayInsert($a_Values, $i_Pos2, $a_Values[$i_Pos1])
            _ArrayDelete($a_Values, UBound($a_Values)-1)
_ArrayDisplay($a_Values, "After-2")
        EndIf

        $s_target = _ArrayToString($a_Values, ",")
        $i_RegWriteResult = RegWrite($r_key, $r_value, "REG_SZ", $s_target)
        If $i_RegWriteResult <> 1 Then
            ConsoleWrite(@CRLF & "Something went terribly wrong while writing the key, so from now on fear the dark - " & $s_source & ": " & @error & @CRLF)
        Else
            ConsoleWrite(@CRLF & "The neccessary changes were made..." & @CRLF)
        EndIf
    Else
        ConsoleWrite(@CRLF & "Everything already in perfect state..." & @CRLF)
    EndIf

EndIf
Edited by cherdeg

Share this post


Link to post
Share on other sites



I'm not sure I entirely understand what you're trying to do, but would you be better off starting with a 2-D array, so that associated data items are held together?

William

Share this post


Link to post
Share on other sites

I do:

* Read Registry value's string

* Write an Backup of original value to the Registry

* Build an array from the original string

* Try to resort that array's elements based on the requirements in my OP <<< this is the part I have trouble with :)

* Build a string from the sorted array

* Write the string back to the Registry

How would you approve the problem with a 2D-Array?

Share this post


Link to post
Share on other sites

Hi cherdeg,

why not deleting "WebClient" and "npnotes" from the array and add them at the end?

Like:

For $i = Ubound($array] -1 To 0 Step -1
 If $array[$i] == "WebClient" Or $array[$i] == "npnotes" Then
   _ArrayDelete($array, $i)
 EndIf
Next

If Ubound($array) < 3 Then _ArrayAdd($array, "")

_ArrayAdd($array, "WebClient")
_ArrayAdd($array, "npnotes")

:)


Regards,Hannes[spoiler]If you can't convince them, confuse them![/spoiler]

Share this post


Link to post
Share on other sites

I imagine a bubble sort would be easy enough to implement. Bubble sorts are slow as a general rule, but they are easy to understand. By the sounds of it though you don't want to sort all the other data, so you could sort it as follows:

1) Make a destination array that contains the unknown elements only, but is of the right length (so +5)

2) Insert the known 5 elements, moving the other elements up (look at the _ArrayInsert code to see how to do this)

Mat

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Hi cherdeg,

why not deleting "WebClient" and "npnotes" from the array and add them at the end?

Yep, of yours, this is it!!!

Easy, simple, obvious. Except if you, like me, can't see the forest for the trees :)

Thank you very much, you made my day!!!

The working code:

; AutoIT-Includes
#include <Array.au3>

; General Variables
Global $r_key = "\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order"
Global $r_value = "ProviderOrder"
Global $s_source
Global $s_target
Global $a_Values
Global $a_ValuesTemp
Global $i_RegWriteResult

; Main
; ==================================================================================================
If @OSArch == "X86" Then $r_key = "HKLM" &  $r_key
If @OSArch == "X64" Then $r_key = "HKLM64" &  $r_key

; Read the original Registry Value
$s_source = RegRead($r_key, $r_value)
If $s_source = "" And @error <> 0 Then
    ConsoleWrite(@CRLF & "Something went terribly wrong while reading the key, so from now on fear the dark - " & $s_source & ": " & @error & @CRLF)
Else
    ; Backup the original Registry Value
    $i_RegWriteResult = RegWrite($r_key, $r_value & "_Backup", "REG_SZ", $s_source)
    If $i_RegWriteResult <> 1 Then
        ConsoleWrite(@CRLF & "Something went terribly wrong while writing the key, so from now on fear the dark - " & $s_source & ": " & @error & @CRLF)
    EndIf

    ; Split to array and delete the relevant elements; all other elements stay untouched and in order
    $a_Values = StringSplit($s_source, ",", 2)
    $a_ValuesTemp = $a_Values
    For $i_i = UBound($a_Values) -1 To 0 Step -1
        If $a_Values[$i_i] == "WebClient" Or $a_Values[$i_i] == "npnotes" Then _ArrayDelete($a_ValuesTemp, $i_i)
    Next
    _ArrayInsert($a_ValuesTemp, 2, "WebClient")
    _ArrayInsert($a_ValuesTemp, 3, "npnotes")
    $a_Values = $a_ValuesTemp

    ; Write the values back to Registry
    $s_target = _ArrayToString($a_Values, ",")
    $i_RegWriteResult = RegWrite($r_key, $r_value, "REG_SZ", $s_target)
    If $i_RegWriteResult <> 1 Then
        ConsoleWrite(@CRLF & "Something went terribly wrong while writing the key, so from now on fear the dark - " & $s_source & ": " & @error & @CRLF)
    Else
        ConsoleWrite(@CRLF & "The neccessary changes were made..." & @CRLF)
    EndIf
EndIf
Edited by cherdeg

Share this post


Link to post
Share on other sites

Hi cherdeg,

glad I could help you! :)


Regards,Hannes[spoiler]If you can't convince them, confuse them![/spoiler]

Share this post


Link to post
Share on other sites

Hi,

I'm somehow stuck: I've got to resort an array of at least the following five values:

"RDPNP", "npnotes", "LanmanWorkstation", "WebClient", "PssoCM32"

There are also situations where the array holds more elements. The values "npnotes" and "WebClient" may appear on any postition of the array. The resort has to conform to the following rules:

1.) After the resort no values must be lost or added; the number of values must stay the same.

2.) "npnotes" has to be the value following directly after "WebClient".

3.) "WebClient" should become element 3 or larger (if there are more than "RDPNP" and "LanmanWorkstation" before it).

4.) All other elements should keep their curent order.

I'm officially too dumb to solve this seemingly easy job - please help...

Best Regards,

Chris

Edit: Here my code so far - it just doesn't work perfekt.

; AutoIT-Includes
#include <Array.au3>

; General Variables
Global $r_key = "\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order"
Global $r_value = "ProviderOrder"
Global $s_source
Global $s_target
Global $a_Values
Global $i_Pos1
Global $i_Pos2
Global $i_RegWriteResult

; Main
; ==================================================================================================
If @OSArch == "X86" Then $r_key = "HKLM" &  $r_key
If @OSArch == "X64" Then $r_key = "HKLM64" &  $r_key

$s_source = RegRead($r_key, $r_value)
If $s_source = "" And @error <> 0 Then
    ConsoleWrite(@CRLF & "Something went terribly wrong while reading the key, so from now on fear the dark - " & $s_source & ": " & @error & @CRLF)
Else
    ; Backup the original Registry Value
    $i_RegWriteResult = RegWrite($r_key, $r_value & "_Backup", "REG_SZ", $s_source)
    If $i_RegWriteResult <> 1 Then
        ConsoleWrite(@CRLF & "Something went terribly wrong while writing the key, so from now on fear the dark - " & $s_source & ": " & @error & @CRLF)
    EndIf

    $a_Values = StringSplit($s_source, ",", 2)
    For $i_i = 0 To UBound($a_Values) - 1
        If $a_Values[$i_i] == "WebClient" Then $i_Pos1 = $i_i
        If $a_Values[$i_i] == "npnotes" Then $i_Pos2 = $i_i
    Next

    If $i_Pos2 <> $i_Pos1+1 Then

_ArrayDisplay($a_Values, "Before")
        If $i_Pos1 == 0 Then
            _ArrayInsert($a_Values, $i_Pos1+3, $a_Values[$i_Pos1])
            _ArrayDelete($a_Values, $i_Pos1)
            _ArrayInsert($a_Values, $i_Pos1+4, $a_Values[$i_Pos2])
            _ArrayDelete($a_Values, $i_Pos2+1)
_ArrayDisplay($a_Values, "After-0")
        ElseIf UBound($a_Values)-1 >= $i_Pos1+1 Then
            _ArrayInsert($a_Values, $i_Pos1+1, $a_Values[$i_Pos2])
            _ArrayDelete($a_Values, $i_Pos2)
_ArrayDisplay($a_Values, "After-1")
        ElseIf UBound($a_Values)-1 = $i_Pos1 Then
            _ArrayInsert($a_Values, $i_Pos2, $a_Values[$i_Pos1])
            _ArrayDelete($a_Values, UBound($a_Values)-1)
_ArrayDisplay($a_Values, "After-2")
        EndIf

        $s_target = _ArrayToString($a_Values, ",")
        $i_RegWriteResult = RegWrite($r_key, $r_value, "REG_SZ", $s_target)
        If $i_RegWriteResult <> 1 Then
            ConsoleWrite(@CRLF & "Something went terribly wrong while writing the key, so from now on fear the dark - " & $s_source & ": " & @error & @CRLF)
        Else
            ConsoleWrite(@CRLF & "The neccessary changes were made..." & @CRLF)
        EndIf
    Else
        ConsoleWrite(@CRLF & "Everything already in perfect state..." & @CRLF)
    EndIf

EndIf

; AutoIT-Includes
#include <Array.au3>

$Str = 'A,B,RDPNP,C,npnotes,D,LanmanWorkstation,WebClient,PssoCM32'
$OutArray = GroupeElements($Str)
_ArrayDisplay($OutArray, "OutArray")

Func GroupeElements($Str)
$SplitArray = StringSplit($Str,",")
Local $j = 1 , $OutArray = $SplitArray , $StrA = ""

For $i = 1 To $SplitArray[0]
if $SplitArray[$i] == "RDPNP" Or $SplitArray[$i] == "LanmanWorkstation" Then ExitLoop
if Not ($SplitArray[$i] == "npnotes") _
And Not ($SplitArray[$i] == "RDPNP") _
And Not ($SplitArray[$i] == "LanmanWorkstation") _
And Not ($SplitArray[$i] == "WebClient") Then
$OutArray[$j] = $SplitArray[$i]
$j += 1
EndIf
Next

For $i = 1 To $SplitArray[0]
if $SplitArray[$i] == "RDPNP" Or $SplitArray[$i] == "LanmanWorkstation" Then

if Not ($SplitArray[$j] == "npnotes") _
And Not ($SplitArray[$j] == "RDPNP") _
And Not ($SplitArray[$j] == "LanmanWorkstation") _
And Not ($SplitArray[$j] == "WebClient") Then $StrA &= $SplitArray[$j] & ","

$OutArray[$j] = $SplitArray[$i]
$j += 1
EndIf
Next


For $i = 1 To $SplitArray[0]
if $SplitArray[$i] == "WebClient" Then

if Not ($SplitArray[$j] == "npnotes") _
And Not ($SplitArray[$j] == "RDPNP") _
And Not ($SplitArray[$j] == "LanmanWorkstation") _
And Not ($SplitArray[$j] == "WebClient") Then $StrA &= $SplitArray[$j] & ","

$OutArray[$j] = "WebClient"
$j += 1
EndIf
Next


For $i = 1 To $SplitArray[0]
if $SplitArray[$i] == "npnotes" Then

if Not ($SplitArray[$j] == "npnotes") _
And Not ($SplitArray[$j] == "RDPNP") _
And Not ($SplitArray[$j] == "LanmanWorkstation") _
And Not ($SplitArray[$j] == "WebClient") Then $StrA &= $SplitArray[$j] & ","

$OutArray[$j] = "npnotes"
$j += 1
EndIf
Next
$StrA = StringTrimRight($StrA,1)

if $StrA == "" Then Return $OutArray

$SplitArray = StringSplit($StrA ,",")
For $i = 1 To $SplitArray[0]
$OutArray[$j] = $SplitArray[$i]
$j += 1
Next

Return $OutArray
EndFunc

صرح السماء كان هنا

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0