2010-11-04 4 views
1

Представьте себе, что у меня есть длинный файл Rebol-форматированных данных, с миллионами строк, которые выглядят как-тоЕсть ли более тонкая детализация, чем LOAD/NEXT для чтения структурированных данных?

REBOL [] 

[ 
    [employee name: {Tony Romero} salary: $10,203.04] 
    [employee name: {Marcus "Marco" Marcami} salary: default] 
    [employee name: {Serena Derella} salary: ($10,000 + $203.04)] 

...

[employee name: {Stacey Christie} salary: (10% * $102,030.40)] 
] 

Если блок вшита не был там, Я мог бы использовать LOAD/NEXT для чтения элементов сотрудника по одному (в отличие от разбора всего файла на структурированные данные с помощью LOAD). Есть ли способ сделать что-то подобное, если закрывающий блок есть?

Что делать, если я хотел вернуться к ранее посещаемому элементу? Может ли быть «структурный поиск»?

Есть ли жизнеспособное решение для баз данных, которое можно было бы использовать для такого рода пожеланий для данных, связанных с Rebol, которые могут даже допускать вставки с произвольным доступом?

ответ

1

Я помню, что именно вы доказали, что это должно быть выполнимо в PARSE? ;-)

Тем не менее, чтобы дать вам полезный ответ: код, который я написал для link text, можно описать точно так же, как разбор (по существу) REBOL, не использующий LOAD/NEXT по умолчанию при необходимости чего-то другого. Итак, посмотрите, прочитайте документацию, запустите тесты, напишите несколько тестов, и если у вас есть еще вопросы, просто спросите.

+0

Использовать PARSE для этого очень интересно, и вы заставили меня задаться вопросом, как LOAD работает под капотом. Когда я посмотрел, я был удивлен, что это мезонин, и он, кажется, ПРОЧИТАЕТ весь источник данных (даже если вы просто делаете/NEXT!) Не уверены в точном детале, но будет ли мезонин LOAD на основе PARSE иметь более инкрементный чтении, и быть способным НАГРУЗИТЬ/НАЗАД? – HostileFork

+0

Одна из проблем заключается в том, что PARSE не будет работать на ПОРТУ! в настоящее время см. http://stackoverflow.com/questions/4127569/using-parse-on-a-port-value – HostileFork

+0

Что касается LOAD/BACK - это, безусловно, можно будет писать, но есть компромисс - требуется время и и использование будет просто исключительным. – Ladislav

1

Если вы счастливы настроить свой формат файла немного, так что это файл с одной записью в строке, не заключающие блоков, ни REBOL заголовка:

employee-name: {Tony Romero} salary: $10203.04 
employee-name: {Marcus "Marco" Marcami} salary: 'default 
employee-name: {Serena Derella} salary: ($10000 + $203.04) 
employee-name: {Stacey Christie} salary: (10% * $102030.40) 

Тогда ....

data: read/lines %data-file.txt 

.... получает вам блок незагруженных строк

Один способ работать с ними, как это:

foreach record data [ 
    record: make object! load/all record 
    probe record 
] 

Я должен был настроить свой формат данных тоже, чтобы сделать его легко загружаемый на REBOL:

  • сотрудника-имя, а не имя сотрудника
  • $ 10203,04, а не $ 10'203.04
  • 10% - только работает с REBOL3

Если вы не можете настроить формат данных, как это, вы всегда можете сделать некоторые изменения для каждой строки до LOAD/ALL, чтобы нормализовать ее для REBOL.

+0

Да, это возможно ... но я надеялся на что-то более надежное в отношении полного спектра формат данных Rebol. Ладислав поднял PARSE, но он не будет работать на PORT!http://stackoverflow.com/questions/4127569/using-parse-on-a-port-value – HostileFork

1

Ответ Sunanda не подходит, поскольку вы можете иметь многострочные данные! Вы можете использовать что-то вроде этого:

 
data: {REBOL [] 

[ 
    [employee name: {Tony Romero} salary: $10'203.04] 
    [employee name: {Marcus "Marco" Marcami} salary: default] 
    [employee name: {Serena Derella} salary: ($10'000 + $203.04)] 
]} 

unless all [ 
    set [value data] load/next data 
    value = 'REBOL 
][ print "Not a REBOL data file!" halt ] 
set [header data] load/next data 
print ["data-file-header:" mold header] 
data: find/tail data #"[" 

attempt [ 
    ;you must use attempt as there will be at least one error at the end of file! 
    ;** Syntax Error: Missing [ at end-of-block 
    indexes: copy [] 
    while [ 
     append indexes data 
     set [loaded-row data] load/next data 
     data 
    ][ 
     probe loaded-row 
    ] 

] 
print "done" 

remove back tail indexes ;removes the last erroneous position 

foreach data-at-pos reverse indexes [ 
    probe first load/next data-at-pos 
] 

Так что результат будет:

 
[employee name: "Tony Romero" salary: $10203.04] 
[employee name: {Marcus "Marco" Marcami} salary: default] 
[employee name: "Serena Derella" salary: ($10000.00 + $203.04)] 
done 
[employee name: "Serena Derella" salary: ($10000.00 + $203.04)] 
[employee name: {Marcus "Marco" Marcami} salary: default] 
[employee name: "Tony Romero" salary: $10203.04] 
+0

также, если у вас есть большой файл данных, вы можете добавить некоторую буферизацию и не читать весь файл сразу. – Oldes

+0

btw .. лучшим решением является не использование закрывающего блока для данных :) – Oldes

+0

ATTEMPT, очевидно, немного изворотлил, так как предполагает, что ваши данные хорошо сформированы. Но спасибо за то, что вы попытаетесь написать код для обходного пути для конкретного сценария, описанного в вопросе. Я действительно размышлял о более обобщенном «поиске», который работал бы на диске, но потом понял, что даже если парсер способен на LOAD/BACK, то невозможность внести изменения будет означать, что это будет полезно только для очень узкий набор условий ... – HostileFork

 Смежные вопросы

  • Нет связанных вопросов^_^