كيفية تحويل بنية بيانات روبي إلى ملف HTML

0

أنا جديد على Stack overflow ، لذا يرجى التفضل إذا انحرف سؤالي عن المستوى المتوقع.

لقد قمت بمعالجة ملف سجل بتنسيق أدناه وأرغب في تكوين تمثيل HTML من بنية البيانات أدناه.

holder = [ 

{:states=>"Texas"}
{:cities=>"Antonio", :data=>{"Ron"=>"26", "Rock"=>"23", "Jake"=>"33"}}
{:cities=>"West_CIT", :data=>{}}
{:cities=>"Austin", :data=>{"Ron"=>"26", "Mike"=>"53", "Jake"=>"36"}}

{:states=>"California"}
{:cities=>"Sacramento", :data=>{"Jill"=>"584", "Rudy"=>"3"}}
{:cities=>"Los Angeles", :data=>{"Jill"=>"4", "Rudy"=>"2"}}

{:states=>"Georgia"}
{:cities=>"Atlanta", :data=>{"Ron"=>"6", "Ross"=>"2", "Jake"=>"35"}}
{:cities=>"Athens", :data=>{"Jill"=>"16", "Mike"=>"4", "Reeves"=>"8"}} ]

أحاول إنشاء ملف HTML يعرض الولايات فقط في الصفحة العلوية ، كما هو موضح أدناه

 <h1> States and Associate Demat details <h1>
 Texas
 California
 Georgia

ولكن عند النقر فوق أي دولة ، يجب توسيعها إلى الشكل أدناه الذي يحتوي على التفاصيل الفرعية

Texas
Antonio     Ron      26
            Rock      23
            Jake     33

West_CIT   

Austin     Ron        26
           Mike       53
           Jake       36

California
Georgia
Likewise the other states. 

لقد ذهبت من خلال وثائق روبي بالإضافة إلى جوهرة نوكوجيري ولكن بمعرفي المحدود في الياقوت (أو أي لغة برمجة) يعيق تقدمي .. هل هذا ممكن حقًا مع روبي أم يجب أن أذهب مع PHP (تعلم مرة أخرى). أبحث عن التوجيه هنا ، شكرا لك.

PS لقد اتخذت هذا كمهمة ذاتية في محاولة لتحسين روبي (أو مهارات البرمجة)

ما كتبته:

holder = []
counter = -1

text = File.open("states.log").read
text.each_line do |line|
  line.strip!
  next if line.empty?
  next if line.include?('persons') || line.include?('demat')
  next if ['-','*'].include? line[0]
  chip = line.split ' '
   if chip.size == 1 and line.start_with?('state')
    holder[counter += 1] = {states: line, data: {}}
    next
  elsif chip.size == 1 and chip = /^(?!.*state_).*$/
    holder[counter += 1] = {cities: line, data: {}}
    next
  end

  chip.each_cons(2) do |key, value|
    holder[counter][:data][key] = value 
    end
end

puts holder

إضافة ملف سجل عينة (الخام)

state_Texas

Antonio

persons                 demat
------------------------------ ----------
Ron                    26
Ron                    23
Jake                   33

=========================================

----Persons

West_CIT

persons                 demat
------------------------------ ----------

=========================================

----Persons

Austin


persons                 demat
------------------------------ ----------
Ron                    26
Mike                   53
Jake                   36

=========================================
state_California

Sacramento


persons                 demat
------------------------------ ----------
Jill                   584
Rudy                   3

=========================================

---- Persons
Los Angeles


persons                 demat
------------------------------ ----------
Jill                   4
Rudy                   2

=========================================

Likewise .......

2 الاجابة

0

أول شيء أولاً: إذا كنت بحاجة إلى تبادل البيانات بين التطبيقات ، أقترح التمسك بتنسيقات قياسية مثل JSON أو YAML . لا أعرف ما إذا كان يمكنك التحكم في تسجيل البيانات أم لا ، ولكن إذا كنت تستطيع ، أقترح تغيير الرمز هناك.

ملف السجل هذا فوضى حقًا ولكنه يحتوي على معلومات كافية لتحويله إلى بنية بيانات روبي مثل المصفوفات والتجزئة.

هناك دائمًا طريقة أفضل ولكن انتهى بي الأمر بهذا الحل.

REJECT_THIS = ["", "------------------------------ ----------", "----Persons", "---- Persons", "persons demat"]
holder = []
separator = '|||'

# here we store the file into the holder, skipping rows in REJECT_THIS
text = File.open("_states.log").read
text.each_line do |line|
  line = line.split.join(' ')
  holder << line unless REJECT_THIS.include? line
end

# just to change the separator mark into a shorter one
holder.map! { |e| e == "=========================================" ? separator : e} 

# map where to split the array grouping by state
split_idxs = holder.map.with_index { |e, i| e [0..4] == 'state' ? i : 0}.uniq[1..-1]<<holder.size

# split the array in states using the index map using the my_split_at_index method and building the states hash
holder = holder.my_split_at_index(split_idxs).map { |element| {element.shift => element} }

# remove 'state_' and convert the key to symbol
holder.map! { |e| e.transform_keys { |key| key[6..-1].to_sym } }

# splits subarrays by separator then build the nested hash
holder.map! do |array|
  array.transform_values do |sub_array|
    split_idxs = sub_array.map.with_index { |e, i| e == separator ? i : 0 }.uniq[1..-1]
    sub_array = sub_array.my_split_at_index(split_idxs).map! { |e| e[0] == separator ? e[1..-1] : e }
    sub_array.map { |element| {city: element.shift, people: element} }
  end
end

# splits the people string
holder.map do |state|
  state.transform_values do |array|
    array.map do |hash|
      hash[:people].map! { |string| string.split(' ') }
    end
  end
end

p holder

في الكود استخدم هذا التصحيح قرد صفيف

class Array

  def my_split_at_index(indexes = [])
    shift = 0
    splitted = []
    indexes.map do |index|
      splitted << self[shift..index-1]
      shift = index
    end
    splitted
  end

end

حامل المتغير الآن عبارة عن مجموعة من التجزئة المتداخلة التي يمكنك استخدامها مع ERB في رمز مثل Dan Hilton المنشور. بنية البيانات الخاصة بالحامل ليست هي نفسها ، لذلك تحتاج إلى تعديل الرمز.

شيء أخير ، لمعرفة كيف هيكل البيانات الخاصة بك YAML تبدو:

require 'yaml'
puts holder.to_yaml
:مؤلف
0

كما قال iGian يمكنك استخدام قوالب ERB لإنشاء HTML الخاص بك. أوصي أيضًا بتغيير بنية بياناتك لتكون أسهل للتكرار. أنت تستخدم حاليًا ترتيب المصفوفة لتحديد مكان المدن. هذا يتطلب فحوصات إضافية على جانب القالب. بدلاً من ذلك ، يجب أن تكون المدن متداخلة في تجزئة الولايات لتبدو كما يلي: {:state => "Texas", :cities=>[{:name => "Antonio", :data=>{"Ron"=>"26", "Rock"=>"23", "Jake"=>"33"}]} . بهذه الطريقة يكون لديك مجموعة من المدن لدولة معينة. باستخدام بنية البيانات هذه ، سيبدو نموذجك كالتالي:

template = ERB.new <<-EOF
    <h1> States and Associate Demat details <h1>
    <% Holder.each do |state| %>
        <h2><%= state[:state] %></h2>
        <% state[:cities].each do |city| %>
            <h3><%= city[:name] %></h3>
            <% city[:data].each do |name, value| %>
                <%= name %> - <%= value %>
            <% end %>
        <% end %>
    <% end %>
EOF

لاحظ أن استخدام <%= %> مع ال = يُستخدم لتغليف تعبيرات الياقوت التي تريد أن تظهر في القالب الخاص بك. من ناحية أخرى <% %> يتم استخدامه لتعيين المتغيرات والتكرار من خلال بنية البيانات الخاصة بك ، ولكن لن تظهر في القالب الخاص بك.

في حالتك ، من المحتمل أن يكون استخدام القوالب مبالغًا فيه ويمكنك التخلص منه File.write('index.html') لكن الحصول على ممارسة ERB مفيد لأنه سيكون قابلاً للتطبيق مباشرةً إذا قررت تعلم Ruby on Rails.

:مؤلف

أسئلة ذات صلة

فوق
قائمة طعام