Page 1 of 1
CSV search... left lookup?
Posted: 27 Jan 2022, 06:20
by ZipZip
1,a,b,c
2,d,e,f
3,g,h,j
Is there a way to search a CSV file and return the left values?
ie...search for "c" and if found return 1,a,b ? or even b,a,1?
bonus question!....a search for "g" ... is it possible to return 3,h,j ?
Thanks for your help!
Re: CSV search... left lookup?
Posted: 27 Jan 2022, 07:36
by mikeyww
Code: Select all
file = %A_ScriptDir%\file.csv
MsgBox, 64, Left from "c", % left(file, "c")
MsgBox, 64, Left from "g", % left(file, "g")
left(file, find) {
Loop, Read, %file%
{ line := [], found := 0
Loop, Parse, A_LoopReadLine, CSV
line.Push(A_LoopField), A_LoopField = find && found := A_Index
If !found
Continue
For each, cell in line
each != found && str .= (str > "" ? "," : "") cell
Return str
}
}
Re: CSV search... left lookup?
Posted: 27 Jan 2022, 11:21
by ZipZip
@mikeyww Thank you for this!
A follow-up question?.... Can the return be put into individual item variables?
search "c" ... and return...
var1 = %item1%
var2 = %item2%
var3 = %item3%
Or do I StringSplit the return?
Thank you!
Re: CSV search... left lookup?
Posted: 27 Jan 2022, 11:28
by mikeyww
I'm not sure what you mean by that. Loop, Read loops through each line. Your post indicates that you would like to search for a field's contents regardless of its position in the line.
Re: CSV search... left lookup?
Posted: 27 Jan 2022, 12:07
by boiler
ZipZip wrote: ↑
Or do I StringSplit the return?
You can have the function return the result as an array so then you can address individual elements of the result:
Code: Select all
file = %A_ScriptDir%\file.csv
resultArr := left(file, "c")
for k, v in resultArr
MsgBox, % "Item " k " left from 'c': " v
Return
left(file, find) {
Loop, Read, %file%
{ line := [], found := 0
Loop, Parse, A_LoopReadLine, CSV
line.Push(A_LoopField), A_LoopField = find && found := A_Index
If !found
Continue
For each, cell in line
each != found && str .= (str > "" ? "," : "") cell
Return Strsplit(str, ",")
}
}
Without using a for-loop, you can address the individual elements as
resultArr.1,
resultArr.2, etc. The number of items in the result is found by
resultArr.Count().
Here it is as a stand-alone demo that uses a string as input instead of reading it from a file:
Code: Select all
text =
(
1,a,b,d,c
2,d,e,f
3,g,h,j
)
resultArr := left(text, "c")
for k, v in resultArr
MsgBox, % "Item " k " left from 'c': " v
Return
left(text, find) {
Loop, Parse, text, `n
{ line := [], found := 0
Loop, Parse, A_LoopField, CSV
line.Push(A_LoopField), A_LoopField = find && found := A_Index
If !found
Continue
For each, cell in line
each != found && str .= (str > "" ? "," : "") cell
Return Strsplit(str, ",")
}
}
You could use this version with a file as well by replacing the assignment to the var
text with:
Code: Select all
FileRead, text, % A_ScriptDir "\file.csv"
Re: CSV search... left lookup?
Posted: 27 Jan 2022, 12:21
by BoBo
Code: Select all
#SingleInstance, Force
FileRead, content, file.csv
toFind :="c"
toShow := [3,2,1] ; show returned items in this order
content := " ; remove this block after testing so the 'FileRead' output is used instead.
(
1,a,b,c
2,d,e,f
3,c,h,i
4,a,t,c
)"
Loop, Parse, content, `n ; parse content using line breaks
InStr(A_LoopField, tofind) ? i:= StrSplit(A_LoopField,",") : "" ; push last line (in case there are multiple occurences) that contains the search pattern) into an array
Loop % i.Count()
res .= i[toShow[A_Index]] ; create output in order that is specified in 'toShow'
MsgBox % res
This will show the result based on the
last found occurrence of the search pattern, so there's still room for improvement. Have phun
Re: CSV search... left lookup?
Posted: 27 Jan 2022, 12:25
by teadrinker
Or like this:
Code: Select all
csv =
(
1,a,b,c
2,d,e,f
3,g,h,j
)
arr := Left(csv, "g")
MsgBox, % arr[1] . " " . arr[2] . " " . arr[3]
arr := Left(csv, "c")
MsgBox, % arr[1] . " " . arr[2] . " " . arr[3]
Left(csv, item) {
RegExMatch(csv, "m`a)^(?=\V*\Q" . item . "\E)\V*$", m)
l := RegExReplace(m, "(,)?\Q" . item . "\E(?(1)|,)")
Return StrSplit(l, ",")
}
Re: CSV search... left lookup?
Posted: 27 Jan 2022, 12:30
by teadrinker
What if you don't know which place
toFind takes?
Re: CSV search... left lookup?
Posted: 27 Jan 2022, 13:55
by Chunjee
If you parse your csv into an object;
https://biga-ahk.github.io/biga.ahk/#/?id=find can find it; easiest if you know what column you are searching in.
Code: Select all
A := new biga() ; requires https://www.npmjs.com/package/biga.ahk
csv := [["a", "b", "c"]
,["d", "e", "f"]
,["g", "h", "i"]]
; find a row that has a "c" in the third collumn
wholerow := A.find(csv, {3: "c"})
; => ["a", "b", "c"]
; find a row that has an "e" in the second collumn
wholerow := A.find(csv, {2: "e"})
; => ["d", "e", "f"]
Re: CSV search... left lookup?
Posted: 27 Jan 2022, 15:45
by ZipZip
Thank you
@mikeyww & also
@boiler for the Strsplit.
Here's what I pieced together....
Code: Select all
find := "c"
Loop, Read, file = %A_ScriptDir%\file.csv
{ line := [], found := 0
Loop, Parse, A_LoopReadLine, CSV
line.Push(A_LoopField), A_LoopField = find && found := A_Index
If !found
Continue
For each, cell in line
each != found && str .= (str > "" ? "," : "") cell
found := Strsplit(str, ",")
var1:= found[1]
var2:= found[2]
var3:= found[3]
}
MsgBox % var1 " " var2 " " var3
Thanks everyone for the posts and ideas. I love this stuff!
Re: CSV search... left lookup?
Posted: 27 Jan 2022, 15:53
by boiler
Is there a particular reason you structured it without using the function left() as mikeyww originally set it up? The function allows you to perform repeated searches without having to repeat the code. You just make a new function call with the new search info. Notice how in mikeyww's original post, he performed two different searches by calling the function twice. You can't do that with the way you've changed it.
Re: CSV search... left lookup?
Posted: 28 Jan 2022, 05:30
by ZipZip
Runs faster without passing the variables.
I'm joking of course . For this help I realized after I saw mikeyww's solution that I only need to run it once. Thanks for your help too boiler. And all the other posts. I really get to learn from seeing all the different solutions.