这个问题来自我之前的问题How to transform a CSV into several lists (applescript)?
我有一个大约4000行的csv文件。我导入它并将每一行作为一个列表的项目,然后我将每行作为它自己的项目列表。
例如:(我使用数字,但我的数据也包含文本,大多数条目都超过1个字符,有些条目也是空白的)
1,2,3,4,5,6
6,5,4,3,2,1
7,8,9,0,7,6
3,4,4,5,3,1
变为
{"1,2,3,4,5,6","6,5,4,3,2,1","7,8,9,0,7,6","3,4,4,5,3,1"}
变为
{{"1","2","3","4","5","6"}{"6","5","4","3","2","1"}{"7","8","9","0","7","6"}{"3","4","4","5","3","1"}}
现在我希望能够做到的是:
从每个列表中删除某些项目,例如我想删除每个列表中的第二个项目,即“2”,“5”,“8”和“4”
对某些项目运行计算,例如我想将项目5乘以2
我的数据中的一些数字在它们的末尾有+11或+17,我想知道如何用匹配的零值替换它,例如,如果我有5002 + 6我我想把它变成5002000000
目前的代码是:
-- Choosing your file
set csvDevices to "testfile.csv"
-- Reading file to memory
set csvDevices to read csvDevices
-- Creating Records (Single Lines)
set csvDevicesRecords to paragraphs of csvDevices
-- Remove Title Line
set csvDevicesRecords to rest of csvDevicesRecords
-- Make each line into a list
set csvDevicesValues to {}
set AppleScript's text item delimiters to ","
repeat with i from 1 to length of csvDevicesRecords
set end of csvDevicesValues to text items of (item i of csvDevicesRecords)
end repeat
set AppleScript's text item delimiters to ""
我希望以上都是有道理的。
答案 0 :(得分:0)
如果你自己写一个子程序来为你做这些事情,那真的不难。这是您要求的3。您需要添加其他子例程,以便进行其他数学运算(加,减和除)。只需复制multiplyItemNumberByValue()子例程并将操作符更改为适当的子例程,它应该无需进一步更改即可使用。
祝你好运。set listOfLists to {{"1", "2+2", "3", "4", "5", "6"}, {"6", "5", "4", "3", "2", "1"}, {"7", "8", "9", "0", "7", "6"}, {"3", "4", "4", "5+3", "3", "1"}}
-- before performing any other operation, expand all zeros
set listOfLists to expandZeros(listOfLists)
-- remove item 2 from every sublist
set listOfLists to removeItemNumber(listOfLists, 2)
-- multiply item 1 of every sublist by 5
set listOfLists to multiplyItemNumberByValue(listOfLists, 1, 5)
(****************** SUBROUTINES ******************)
on multiplyItemNumberByValue(listOfLists, itemNumber, theValue)
set newList to {}
repeat with i from 1 to count of listOfLists
set thisList to item i of listOfLists
set thisItem to item itemNumber of thisList
set newValue to (thisItem as number) * theValue
set item itemNumber of thisList to (newValue as text)
set end of newList to thisList
end repeat
return newList
end multiplyItemNumberByValue
on removeItemNumber(listOfLists, itemNumber)
set newList to {}
repeat with i from 1 to count of listOfLists
set thisList to item i of listOfLists
if itemNumber is equal to 1 then
set newSublist to items 2 thru end of thisList
else if itemNumber is equal to (count of thisList) then
set newSublist to items 1 thru (itemNumber - 1) of thisList
else
set newSublist to items 1 thru (itemNumber - 1) of thisList & items (itemNumber + 1) thru end of thisList
end if
set end of newList to newSublist
end repeat
return newList
end removeItemNumber
on expandZeros(listOfLists)
set newList to {}
repeat with i from 1 to count of listOfLists
set thisList to item i of listOfLists
set newSublist to {}
repeat with j from 1 to count of thisList
set subItem to item j of thisList
if subItem contains "+" then
set x to offset of "+" in subItem
if x is equal to 0 or x is equal to 1 or x is equal to (count of subItem) then
set end of newSublist to subItem -- do nothing
else
set a to text 1 thru (x - 1) of subItem
set b to text (x + 1) thru end of subItem
repeat (b as number) times
set a to a & "0"
end repeat
set end of newSublist to a
end if
else
set end of newSublist to subItem -- do nothing
end if
end repeat
set end of newList to newSublist
end repeat
return newList
end expandZeros
这是其他数学子程序......
on divideItemNumberByValue(listOfLists, itemNumber, theValue)
set newList to {}
repeat with i from 1 to count of listOfLists
set thisList to item i of listOfLists
set thisItem to item itemNumber of thisList
set newValue to (thisItem as number) / theValue
set item itemNumber of thisList to (newValue as text)
set end of newList to thisList
end repeat
return newList
end divideItemNumberByValue
on addValueToItemNumber(listOfLists, itemNumber, theValue)
set newList to {}
repeat with i from 1 to count of listOfLists
set thisList to item i of listOfLists
set thisItem to item itemNumber of thisList
set newValue to (thisItem as number) + theValue
set item itemNumber of thisList to (newValue as text)
set end of newList to thisList
end repeat
return newList
end addValueToItemNumber
on subtractValueFromItemNumber(listOfLists, itemNumber, theValue)
set newList to {}
repeat with i from 1 to count of listOfLists
set thisList to item i of listOfLists
set thisItem to item itemNumber of thisList
set newValue to (thisItem as number) - theValue
set item itemNumber of thisList to (newValue as text)
set end of newList to thisList
end repeat
return newList
end subtractValueFromItemNumber
答案 1 :(得分:0)
Nigel Garvey's CSV-to-list converter是我见过的最好的。
您可以这样称呼它:
set filePath to "/Users/You/Desktop/myCsv.csv"
set csvData to do shell script "cat " & quoted form of filePath
set csvDevicesLists to csvToList(csvData, {trimming:true})
--> {{"1", "2", "3", "4", "5", "6"}, {"6", "5", "4", "3", "2", "1"}, {"7", "8", "9", "0", "7", "6"}, {"3", "4", "4", "5", "3", "1"}}
你可以像这样填充零:
set xxx to {{"1", "2", "3+2", "4", "52+3", "6"}, {"6", "5", "4+5", "3", "2", "1"}}
repeat with i from 1 to count of xxx
if (item i of xxx as text) contains "+" then
set temp to {}
repeat with anItem in item i of xxx
set end of temp to (do shell script "echo " & quoted form of anItem & " | sed s/+/*10^/ | bc")
end repeat
set item i of xxx to temp
end if
end repeat
return xxx
ASObjC Runner也为操作列表提供了一些很好的工具。
答案 2 :(得分:-2)
使用Ruby或Python(或几乎任何其他语言)会更容易:
"1,2,3+11,4,5,6
6,5,4,3,2,1+17".split("\n").each { |n|
n.gsub!(/\+(\d+)/, "0" * $1.to_i)
c = n.split(",")
c[4] = c[4].to_i * 5
c.delete_at(1)
puts c.join(",")
}