0Pricing
Lua Academy · درس

الجداول المتداخلة والبيانات المهيكلة

أنشئ بُنى متداخلة وادخل إلى الحقول العميقة

الجداول المتداخلة والبيانات المهيكلة درس مجاني في Lua Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Lua Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Lua Academy 4 دروس في المجموع.

أساسيات الجداول المتداخلة

يمكن أن تحتوي الجداول على جداول أخرى بوصفها قيمًا، مما ينشئ بنى عميقة بأي مستوى. يمكنكم الوصول إلى الحقول المتداخلة بتسلسل النقاط أو الأقواس. وتؤدي الجداول الوسيطة المفقودة إلى أخطاء؛ لذا تأكدوا دائمًا من وجود الجداول الأب قبل الوصول إلى الحقول العميقة.

local company = {
  name = "CoddyKit",
  address = {
    city = "Istanbul",
    country = "Turkey",
    zip = "34000"
  },
  employees = 25
}

print(company.name)            -- CoddyKit
print(company.address.city)    -- Istanbul
print(company["address"]["zip"]) -- 34000

الوصول الآمن إلى الحقول العميقة

يؤدي الوصول إلى حقل في قيمة nil إلى حدوث عطل مع ظهور الرسالة "attempt to index a nil value". احموا من ذلك باستخدام التقييم القصير لـ and: t and t.a and t.a.b. وتعرّف بعض قواعد الشيفرة مساعدًا مثل get(t, ...) لاجتياز سلسلة من المفاتيح بأمان.

local function get(t, ...)
  local cur = t
  for _, key in ipairs({...}) do
    if type(cur) ~= "table" then return nil end
    cur = cur[key]
  end
  return cur
end

local data = {user = {profile = {age = 30}}}
print(get(data, "user", "profile", "age"))    -- 30
print(get(data, "user", "missing", "field"))  -- nil

مصفوفة من السجلات

من الأنماط الشائعة مصفوفة من الجداول (السجلات). كل عنصر هو جدول يحتوي على حقول مُسمّاة. كرّروا باستخدام ipairs، ثم الوصول إلى الحقول بأسمائها. وهذا هو المقابل في Lua لمصفوفة من الكائنات أو قائمة من البنى.

local users = {
  {id=1, name="Alice", score=95},
  {id=2, name="Bob",   score=87},
  {id=3, name="Carol", score=91},
}

for _, user in ipairs(users) do
  print(user.id, user.name, user.score)
end

إنشاء الجداول المتداخلة ديناميكيًا

أنشئوا البنى المتداخلة تدريجيًا بإنشاء الجداول الداخلية عند الحاجة. احرصوا دائمًا على تهيئة الجدول قبل الإدراج فيه. ومن الأخطاء الشائعة نسيان إنشاء الجدول الداخلي أولًا، ثم محاولة الفهرسة في قيمة nil.

local tree = {}
tree.root = {value = 10}
tree.root.left = {value = 5}
tree.root.right = {value = 15}
tree.root.left.left = {value = 2}

print(tree.root.value)            -- 10
print(tree.root.left.value)       -- 5
print(tree.root.left.left.value)  -- 2

الجدول بوصفه إعدادًا شبيهًا بـ JSON

تُستخدم جداول Lua غالبًا في ملفات الإعداد، على نحو مشابه لـ JSON أو YAML. يُرجع الملف جدولًا، ثم يحمّله التطبيق باستخدام dofile() أو require(). وتمثل الجداول المتداخلة أقسام الإعداد المتداخلة.

-- config.lua (returned table)
local config = {
  server = {
    host = "0.0.0.0",
    port = 8080,
    ssl  = false,
  },
  db = {
    host = "localhost",
    name = "appdb",
    pool_size = 10,
  },
  logging = { level = "info", file = "/var/log/app.log" }
}

print(config.server.port)      -- 8080
print(config.db.pool_size)    -- 10

الرسم البياني بوصفه قائمة تجاور

مثّلوا الرسم البياني بجدول من الجداول: كل مفتاح هو عقدة، وقيمته قائمة بالجيران. ويتميز تمثيل قائمة التجاور هذا بكفاءة استخدام الذاكرة في الرسوم البيانية قليلة الكثافة، كما يسهل التعامل معه في Lua.

local graph = {
  A = {"B", "C"},
  B = {"A", "D"},
  C = {"A", "D"},
  D = {"B", "C"},
}

-- BFS from A
local visited = {A=true}
local queue = {"A"}
while #queue > 0 do
  local node = table.remove(queue, 1)
  io.write(node .. " ")
  for _, neighbor in ipairs(graph[node]) do
    if not visited[neighbor] then
      visited[neighbor] = true
      queue[#queue+1] = neighbor
    end
  end
end
print()  -- A B C D

تعديل الحقول المتداخلة

عدّلوا الحقول المتداخلة بالوصول إلى الجدول الأب وإسناد قيمة إلى المفتاح. وبما أن الجداول تُمرّر بالمرجع، يمكن لأي دالة تستقبل جدولًا تعديل محتوياته مباشرةً، وسيرى المستدعي هذه التغييرات.

local player = {name="Hero", stats={hp=100, mp=50, atk=20}}

local function takeDamage(p, dmg)
  p.stats.hp = math.max(0, p.stats.hp - dmg)
end

takeDamage(player, 35)
print(player.stats.hp)   -- 65

player.stats.atk = player.stats.atk + 5
print(player.stats.atk)  -- 25

تسلسل الجداول المتداخلة

يفيد تحويل جدول متداخل إلى نص في تصحيح الأخطاء أو التسجيل. ويمكن لمُسلسل递归ي بسيط التعامل مع أي عمق، لكنه لن يتعامل مع الدورات (المراجع الدائرية).

local function serialize(val, indent)
  indent = indent or 0
  local pad = string.rep("  ", indent)
  if type(val) ~= "table" then
    return tostring(val)
  end
  local parts = {"{"}
  for k, v in pairs(val) do
    parts[#parts+1] = pad.."  "..tostring(k).."="..serialize(v,indent+1)
  end
  parts[#parts+1] = pad.."}"
  return table.concat(parts, "\n")
end
local data = {x=1, nested={y=2, z=3}}
print(serialize(data))

المصفوفات المتناثرة

يؤدي تخزين مصفوفة ثنائية الأبعاد بطريقة مباشرة إلى هدر الذاكرة عند التعامل مع مدخلات متناثرة كبيرة. خزّنوا الإدخالات غير الصفرية فقط في جدول متداخل: matrix[row][col] = value. ويمكن لهذا التمثيل التعامل بكفاءة مع مصفوفات ضخمة عندما تكون معظم القيم صفرًا.

local function newMatrix()
  return setmetatable({}, {__index=function(t,k)
    local row = {}
    rawset(t, k, row)
    return row
  end})
end

local m = newMatrix()
m[1][1] = 5
m[3][7] = 12
m[100][200] = 99

print(m[1][1])    -- 5
print(m[3][7])    -- 12
print(m[2][5])    -- nil (sparse: no value)

التحقق من المساواة العميقة

تُقارن الجداول حسب المرجع باستخدام ==، وليس حسب القيمة. ولمقارنة الجداول المتداخلة بنيويًا، اكتبوا دالة مساواة递归ية تقارن كل زوج مفتاح-قيمة، وتستدعي نفسها على الجداول المتداخلة.

local function deepEqual(a, b)
  if type(a) ~= type(b) then return false end
  if type(a) ~= "table" then return a == b end
  for k, v in pairs(a) do
    if not deepEqual(v, b[k]) then return false end
  end
  for k in pairs(b) do
    if a[k] == nil then return false end
  end
  return true
end
print(deepEqual({1,{2,3}},{1,{2,3}}))  -- true
print(deepEqual({1,{2,3}},{1,{2,4}}))  -- false

تحقق سريع

ماذا يحدث عند الوصول إلى t.a.b إذا كانت قيمة t.a هي nil؟

مراجعة: الجداول المتداخلة

الملخص:

  • يمكن تداخل الجداول بأي عمق: t.a.b.c
  • احموا الوصول العميق: t and t.a and t.a.b
  • الجداول أنواع مرجعية، لذا تعدّل الدوال محتوياتها مباشرةً
  • مصفوفة من السجلات: {{name=...},{name=...}}
  • المصفوفة المتناثرة: جداول متداخلة لكفاءة استخدام الذاكرة
  • تتطلب المساواة العميقة مقارنةً递归ية

الأسئلة الشائعة

هل درس «الجداول المتداخلة والبيانات المهيكلة» مجاني؟

نعم — نص درس «الجداول المتداخلة والبيانات المهيكلة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Lua Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Lua Academy 4 دروس في المجموع.

ماذا ستتعلم في «الجداول المتداخلة والبيانات المهيكلة»؟

أنشئ بُنى متداخلة وادخل إلى الحقول العميقة تتمرن على Lua Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Lua Academy؟

لا تُشترط خبرة سابقة. Lua Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «الجداول المتداخلة والبيانات المهيكلة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Lua Academy هذا؟

نعم. كل درس في Lua Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الجداول بوصفها مصفوفات
  2. الجداول بوصفها قواميس
  3. التكرار عبر الجداول باستخدام pairs وipairs
  4. الجداول المتداخلة والبيانات المهيكلة
← العودة إلى Lua Academy