I have a file called file1.txt whose contents are as described below
Contents for file1.txt:
AND 60
NAND 20
OR 30
SUN 90
SIN 10
SIM 80
EW 25
NEW 85
PHEW 55
So, total the file has 9 lines with two empty lines , data contains 2 columns and 3 rows in every group and there are 3 such groups with two empty lines between them. Write a Tcl code to read file1.txt is possible use Hashes to sort these 3 groups and print 3 groups in ascending order. as shown below Output:
NAND 20
OR 30
AND 60
SIN 10
SIM 80
SUN 90
EW 25
PHEW 55
NEW 85
When you write the code make it elastic and scalable to data input containing hundreds of such groups and don't limit it for only 3 groups containing 3 entries
I already tried below code and this does not give correct output
# Function to read the file and organize data into a hash
proc readAndOrganizeDataFromFile {filename} {
set fileId [open $filename]
set data [read $fileId]
close $fileId
set groups [split $data "\n\n"]
set hashTable [dict create]
foreach group $groups {
set lines [split $group "\n"]
foreach line $lines {
if {$line eq ""} {
continue ;# Skip empty lines
}
set parts [split $line]
set key [lindex $parts 0]
set value [lindex $parts 1]
dict lappend hashTable $key $value
}
}
return $hashTable
}
# Function to sort and print the hash table
proc sortAndPrintHash {hashTable} {
set sortedKeys [lsort -dictionary [dict keys $hashTable]]
foreach key $sortedKeys {
set values [dict get $hashTable $key]
set output [join $values " "]
puts $output
}
}
# Example usage
set filename "file1.txt"
set hashTable [readAndOrganizeDataFromFile $filename]
sortAndPrintHash $hashTable
There are several problems:
split
command incorrectly: split string ?splitChars?
Returns a list created by splitting string at each character that is in
the splitChars argument.
When splitChars
is set as "\n\n"
it means to split the string by every "\n"...not by two \n
characters in a row. splitChars
is a set of individual characters, not an exact string.
You're not preserving the original data by the original groups.
All the data is going into one big flat dict. There's no way to report it back by groups again.
You're sorting the data by key, not value.
My suggestion is to read the orginal file as a dict where key is the group number and the value is a list of lists. Then sort each value of the dict with lsort -index 1
in order to sort each value by the second element in each list.
proc readAndOrganizeDataFromFile {filename} {
set fileId [open $filename]
set data [read $fileId]
close $fileId
set hashTable [dict create]
set lines [split $data "\n"]
set group_num 0
foreach line $lines {
if {$line eq ""} {
incr group_num
continue
}
# key = group_num
# value = list of lines
dict lappend hashTable $group_num $line
}
return $hashTable
}
proc sortAndPrintHash {hashTable} {
set sortedKeys [lsort -dictionary [dict keys $hashTable]]
foreach key $sortedKeys {
set values [dict get $hashTable $key]
set sorted_value [lsort -dictionary -index 1 $values]
foreach value $sorted_value {
puts $value
}
puts ""
}
}
# Example usage
set filename file1.txt
set hashTable [readAndOrganizeDataFromFile $filename]
sortAndPrintHash $hashTable