0

这个问题是我之前的问题How to transform a CSV into multiple 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 ""

我希望以上所有内容都有意义。

4

3 回答 3

1

如果您自己编写一个子程序来为您做这些事情,这真的不难。这是你要求的 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
于 2013-02-19T18:22:24.667 回答
0

Nigel Garvey 的 CSV 到列表转换器是我见过的最好的。

你可以这样称呼它:

    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还提供了一些用于操作列表的好工具。

于 2013-02-20T05:46:42.010 回答
-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(",")
}
于 2013-02-19T19:53:02.160 回答