কিভাবে একটি লুয়া টেবিল এন্ট্রি সংখ্যা পেতে?


132

"আমাকে এটি আপনার জন্য গুগল করুন" প্রশ্নের মতো মনে হচ্ছে তবে কোনওভাবেই আমি উত্তর খুঁজে পাচ্ছি না। লুয়া #অপারেটর কেবল পূর্ণসংখ্যা কী সহ এন্ট্রি গণনা করে এবং তাই করে table.getn:

tbl = {}
tbl["test"] = 47
tbl[1] = 48
print(#tbl, table.getn(tbl))   -- prints "1     1"

count = 0
for _ in pairs(tbl) do count = count + 1 end
print(count)            -- prints "2"

আমি কীভাবে সমস্ত এন্ট্রিগুলি গণনা না করে নম্বর পাব ?


3
@ এলএইচএফ: আমি একটি সিরিয়ালাইজার লিখেছি যা এটি প্রত্যক্ষিত প্রতিটি বস্তুর মনে রাখে এবং পরের বার এটি দেখলে এটি বস্তুর পরিবর্তে পূর্ণসংখ্যার রেফারেন্স প্রকাশ করে। এটি লেখার প্রাকৃতিক উপায়টি হ'ল কিছু dictionary[value] = #dictionary + 1, যেখানে সমস্ত বস্তুর #সংখ্যাকে উপস্থাপন করে । কি আমি ভাবছি কেন তুমি না এই চাই: সব বিবেকী # (kaizer.se দ্বারা উত্তর দেখুন) জন্য ব্যবহারে ক্ষেত্রে, সমস্ত বস্তু গণনা ঠিক কি # ইতিমধ্যে আয় সমান; দেখে মনে হচ্ছে # গণনা করা সবকিছুই কঠোরভাবে একটি উন্নতি। অবশ্যই আমি একজন লুয়া নবাগত এবং সম্ভবত পয়েন্টটি মিস করছি।
রোমান স্টারকভ

32
@ এলএইচএফ: সমস্ত যুক্তিসঙ্গত প্রোগ্রামিং ভাষার জন্য একটি সাধারণ ক্রিয়াকলাপ রয়েছে তার জন্য কেন তাকে এমন কিছু করা দরকার কেন তা জিজ্ঞাসা করে প্রোগ্রামারের দক্ষতা নিয়ে প্রশ্ন করা আপনার পক্ষে মোটেই সুন্দর নয়।
টিমভি

5
@ টিমউই: লুয়া ভাষার অন্যতম লেখককে বলা আপনার পক্ষে মোটেই সুন্দর নয় যে লুয়া "যুক্তিসঙ্গত" প্রোগ্রামিং ভাষার মধ্যে নেই। ;-) বিটিডাব্লু, আমারও সেই তথ্যের প্রয়োজন হয়নি।
আলেকজান্ডার গ্ল্যাডিশ

5
আমি কখনও মনে করি না যে আমি কোনও একক ভাষার প্রতিটি বৈশিষ্ট্যই ব্যবহার করেছি । এর অর্থ এই নয় যে তারা অন্যের পক্ষে দরকারী নয় :)
রোমান স্টারকভ

7
@ সাইলভানার আমার মতে, #অপারেটরটি কেবলমাত্র সংজ্ঞায়িত। এটি এত সহজেই স্থিরযোগ্য: প্রথমত, #ডিটারমিনিস্টিক তৈরি করুন এবং দ্বিতীয়ত, রঙিন গণনা পাওয়ার জন্য কোনও নতুন অপারেটর বা ফাংশন প্রবর্তন করুন। গল্পের সমাপ্তি ... কেন তাদের এত অনড় থাকতে হবে? :)
রোমান স্টারকভ

উত্তর:


129

আপনার কাছে ইতিমধ্যে প্রশ্নের সমাধান রয়েছে - কেবলমাত্র একমাত্র উপায়টি দিয়ে পুরো টেবিলটি পুনরাবৃত্তি করা pairs(..)

function tablelength(T)
  local count = 0
  for _ in pairs(T) do count = count + 1 end
  return count
end

এছাড়াও, লক্ষ্য করুন যে "#" অপারেটরের সংজ্ঞা তার চেয়ে কিছুটা জটিল। আমাকে এই টেবিলটি গ্রহণ করে তা বর্ণনা করুন:

t = {1,2,3}
t[5] = 1
t[9] = 1

ম্যানুয়াল অনুসারে , 3, 5 এবং 9 এর যে কোনওটিই এর বৈধ ফলাফল #t। এটিকে ব্যবহার করার একমাত্র বুদ্ধিমান উপায় হ'ল শূন্যমূল্য ব্যতীত একটি স্বতন্ত্র অংশের অ্যারেগুলি।


42
আমি এখনও লুয়ার সাথে আমার অভিজ্ঞতার স্মৃতিতে কাঁপছি, যখন আমি প্রথম উপলব্ধি করেছিলাম যে বেসিক অপারেটরের রিটার্ন ভ্যালু হ্রাসকারী #নয়।
রোমান স্টারকভ

5
ওহ, এটি সম্ভবত নির্বিচারে। এটি ঠিক একই জিনিস যখন সি স্ট্যান্ডার্ড কিছু বাস্তবায়ন সংজ্ঞায়িত আচরণ হতে ছেড়ে যায় leaves এটির মতো হওয়ার কারণ হ'ল বিভিন্ন বাস্তবায়নকারী বিভিন্ন প্রয়োগের পছন্দ বাছাই করতে পারেন।
নেকিডেবল

19
According to the manual, any of 3, 5 and 9 are valid results for #t। ম্যানুয়াল অনুসারে, অ-সিকোয়েন্সগুলিতে # কল করা সংজ্ঞায়িত । তার মানে যে কোনও ফলাফল (-1, 3, 3.14, 5, 9) বৈধ।
cubspl42

6
বৈধ ফলাফল সম্পর্কিত: u0b34a0f6ae লুয়া 5.1 এর জন্য সঠিক, এবং কিউবস্পস্প্লিউ ৪৫ লুয়া ৫.২ এর জন্য সঠিক। উভয় ক্ষেত্রেই পুরো বিষয়টি সম্পূর্ণ উন্মাদ।
জেরেমি

9
# নন-সিক্যুয়েন্সে # ব্যতিক্রম ঘটায় না এমনটি হ'ল লুয়া ব্যবহার করে নিজেকে আরও ভাল বোধ করার জন্য কিছুটা কাটানোর মতো করে তোলে।
নৌকা কোডার

21

আপনি এন্ট্রি সংখ্যা ট্র্যাক করতে একটি মেটা টেবিল সেট আপ করতে পারেন, এই তথ্য ঘন ঘন প্রয়োজন হয় এটি পুনরাবৃত্তির চেয়ে দ্রুত হতে পারে।


এই পদ্ধতির সাহায্যে মুছে ফেলা ইন্ট্রিগুলি পরিচালনা করার কোনও সুবিধাজনক উপায় নেই?
u0b34a0f6ae

দুঃখজনকভাবে, এটি সূচকটি উপস্থিত না থাকলে __newindex ফাংশনটি শূণ্য কার্যভারগুলিতে কাজ করে না বলে মনে হয়, তাই মনে হচ্ছে আপনাকে একটি বিশেষ ফাংশনের মাধ্যমে এন্ট্রি অপসারণের কাজটি করতে হবে।
এরগোসিস

1
আপনার পৃথক সারণীতে ডেটা সংরক্ষণ করা উচিত (উদাহরণস্বরূপ __index এবং __newindex এর আপলিউ হিসাবে অ্যাক্সেসযোগ্য)। তারপরে প্রতিটি ছক অ্যাক্সেসের জন্য __index এবং __newindex উভয়ই আগুন জ্বালিয়ে দিতে পারে। পারফরম্যান্সটি গ্রহণযোগ্য কিনা তা আপনার পরীক্ষা করা উচিত।
আলেকজান্ডার গ্ল্যাডিশ

@ আলেকজান্ডার: হ্যাঁ হ্যাঁ, এবং তারপরে পরবর্তী হোঁচট খাওয়া: আপনি যদি টেবিলের প্রক্সি করেন তবে জোড় দিয়ে সাধারণ পুনরাবৃত্তিটি কার্যকর হয় না। এটি লুয়া 5.2 এ সমাধান করা সম্ভব হবে, শুনেছি।
u0b34a0f6ae

5.2-এ __ জোড়া এবং __পরি প্রতিযোগিতাগুলি থাকবে ... আপনি যদি 5.1-এ এটি করতে চান তবে আপনাকে নিজের সাথে জোড়া () ফাংশনটি প্রতিস্থাপন করতে হবে। তবে এটি সম্ভবত খুব বেশি। :-)
আলেকজান্ডার গ্ল্যাডিশ

3

একটি উপায় আছে, তবে এটি হতাশ হতে পারে: গণনাটি সংরক্ষণের জন্য অতিরিক্ত ভেরিয়েবল (বা টেবিলের ক্ষেত্রের একটি) ব্যবহার করুন এবং প্রতিবার আপনি যখন কোনও সন্নিবেশ করান তখন এটি বাড়ান।

count = 0
tbl = {}

tbl["test"] = 47
count = count + 1

tbl[1] = 48
count = count + 1

print(count)   -- prints "2"

অন্য কোনও উপায় নেই, # অপারেটর কেবল একটানা কী সহ অ্যারে-জাতীয় টেবিলে কাজ করবে।


3
এটি একটি প্রক্সি টেবিল এবং রূপকগুলির সাথে স্বয়ংক্রিয়ভাবে তৈরি করা যেতে পারে, যেমন এরগোসিসের উত্তর
আরবেরটিগ

আমি মন্তব্য থেকে ধারণা পেয়েছি যে প্রক্সিযোগ্য / রূপক জিনিসগুলি এখনও এই দৃশ্যটিকে পুরোপুরি সমর্থন করে না, তাই আমি বর্তমানে এটি উপলব্ধ সেরা উপায় হিসাবে গ্রহণ করব।
রোমান স্টারকভ

সারণীগুলির জন্য একমাত্র উপায় গণনা এবং টেবিলগুলি তৈরি করার সময় একটি লাইন যুক্ত করা যখনই আপনার গণনার প্রয়োজন হয় ততবার এগুলি গণনা করার চেয়ে ফাংশনটির চেয়ে ভাল। আপনি গণনায় মান সেট করে শেষে একটি কী যুক্ত করতে পারেন।
হেনরিক এরল্যান্ডসন

2

কোনও টেবিলে প্রবেশের সংখ্যা পাওয়ার সবচেয়ে সহজ উপায়টি হ'ল '#' দিয়ে। #tableName যতক্ষণ এন্ট্রি সংখ্যা হিসাবে গণ্য করা হয়:

tbl={
    [1]
    [2]
    [3]
    [4]
    [5]
}
print(#tbl)--prints the highest number in the table: 5

দুঃখের বিষয়, যদি তাদের নম্বর না দেওয়া হয় তবে এটি কার্যকর হবে না।


2

আপনি পেনলাইট লাইব্রেরি ব্যবহার করতে পারেন । এটিতে একটি ফাংশন রয়েছে sizeযা টেবিলের আসল আকার দেয়।

এটি লুয়াতে প্রোগ্রামিং এবং অনুপস্থিত থাকার সময় আমাদের প্রয়োজন হতে পারে এমন অনেকগুলি কার্যকারিতা বাস্তবায়ন করেছে।

এটি ব্যবহারের জন্য নমুনা এখানে।

> tablex = require "pl.tablex"
> a = {}
> a[2] = 2
> a[3] = 3 
> a['blah'] = 24

> #a
0

> tablex.size(a)
3

1
local function CountedTable(x)
    assert(type(x) == 'table', 'bad parameter #1: must be table')

    local new_t = {}
    local mt = {}

    -- `all` will represent the number of both
    local all = 0
    for k, v in pairs(x) do
        all = all + 1
    end

    mt.__newindex = function(t, k, v)
        if v == nil then
            if rawget(x, k) ~= nil then
                all = all - 1
            end
        else
            if rawget(x, k) == nil then
                all = all + 1
            end
        end

        rawset(x, k, v)
    end

    mt.__index = function(t, k)
        if k == 'totalCount' then return all
        else return rawget(x, k) end
    end

    return setmetatable(new_t, mt)
end

local bar = CountedTable { x = 23, y = 43, z = 334, [true] = true }

assert(bar.totalCount == 4)
assert(bar.x == 23)
bar.x = nil
assert(bar.totalCount == 3)
bar.x = nil
assert(bar.totalCount == 3)
bar.x = 24
bar.x = 25
assert(bar.x == 25)
assert(bar.totalCount == 4)

1
উত্তর পোস্ট করার সময়, সর্বনিম্ন পরিমাণের কোড পোস্ট করার পরামর্শ দেওয়া হয় যা সরাসরি কোনও প্রশ্নের উত্তর দেয় এবং কোডটি কীভাবে প্রশ্নের উত্তর দেয় তা ব্যাখ্যা করে। এখানে দেখুন
cst1992

__newindexকেবলমাত্র একটি নতুন কী সংজ্ঞায়িত হলে কল করুন, সুতরাং __newindexযখন আমরা nilএকটি বিদ্যমান কী তে সেট করি তখন কল করার কোনও সুযোগ থাকে না।
ফ্রাঙ্ক এ কে

-1

সারণির উপাদানগুলি সন্নিবেশ পদ্ধতিতে যুক্ত করা হয় বলে মনে হয় সঠিকভাবে ফিরে আসবে। অন্যথায়, আমাদের সমস্ত উপাদান গণনা করতে হবে

mytable = {}
element1 = {version = 1.1}
element2 = {version = 1.2}
table.insert(mytable, element1)
table.insert(mytable, element2)
print(table.getn(mytable))

এটি 2 টি সঠিকভাবে মুদ্রণ করবে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.