2009-09-11 25 views
25

मूल पोस्टकड़ी

को देखते हुए कोई लुआ में समारोह में बनाया गया है कि वहाँ, मैं एक समारोह है कि मुझे टेबल एक साथ संलग्न करने के लिए अनुमति देता है की तलाश में हूँ। मैंने काफी हद तक गुस्सा किया है और मैंने हर समाधान की कोशिश की है, लेकिन कोई भी ठीक से काम नहीं कर रहा है।

परिदृश्य इस प्रकार है: मैं एक आवेदन में लूआ का उपयोग कर रहा हूं। एप्लिकेशन का एक आंतरिक आदेश तालिका के रूप में मानों की एक सूची देता है।

जो मैं करने की कोशिश कर रहा हूं वह उस लूप में रिकर्सिवली कॉल को कॉल करता है और लौटाए गए मानों को फिर से तालिका के रूप में, पिछले पुनरावृत्तियों से तालिका में जोड़ता है।


संपादित

जो लोग भविष्य में इस पोस्ट दिखाई देती के लिए, कृपया ध्यान दें कि पोस्ट @gimf। चूंकि लुआ में टेबल्स किसी और चीज की तुलना में सरणी की तरह हैं (यहां तक ​​कि एक सूची संदर्भ में), एक टेबल को दूसरे में जोड़ने का कोई वास्तविक सही तरीका नहीं है। निकटतम अवधारणा तालिकाओं का विलय हो रही है। कृपया उस संबंध में सहायता के लिए, "Lua - merge tables?" पोस्ट देखें।

+0

संभावित शिकार को श्रेणीबद्ध करने के लिए : http://stackoverflow.com/questions/1283388/lua-merge-tables। आप "लूप में रिकर्सिवली" का जिक्र करते हैं। क्या आप गहरी प्रतिलिपि + विलय की खोज करते हैं? – gimpf

+0

निम्नलिखित लिंक हैं जो मैंने पाया है: http://ardoris.wordpress.com/2008/08/10/lua-merge-two-tables-awesome3-rc2-config/ http: // www.idevgames.com/forum/archive/index.php/t-10223.html हालांकि मैं प्रत्येक के दृष्टिकोण को समझता हूं, न ही काम करता प्रतीत होता है। क्या आपके पास एक समाधान समाधान है? –

+0

gimpf, शायद मैं पूरी तरह स्पष्ट नहीं हूं। मर्जिंग टेबल और कॉन्सटेटिंग टेबल समान हैं लेकिन बहुत अलग हैं। मुझे एक टेबल को दूसरे में जोड़ने में दिलचस्पी है, इस प्रकार शब्दकोष शब्द का उपयोग। –

उत्तर

2

यदि आप दो टेबल मर्ज करना चाहते हैं, लेकिन परिणाम तालिका की गहरी प्रतिलिपि की आवश्यकता है, किसी भी कारण से, another SO question on merging tables से विलय का उपयोग करें और lua-users से कुछ गहरी प्रतिलिपि कोड का उपयोग करें।

(संपादित ठीक है, हो सकता है आप अपने प्रश्न संपादित कर सकते हैं एक न्यूनतम उदाहरण प्रदान करने के लिए ... आप का मतलब है कि एक मेज

{ a = 1, b = 2 } 

एक और टेबल के साथ concatenated हैं

{ a = 5, b = 10 } 

चाहिए परिणाम

{ a = 1, b = 2, a = 5, b = 10 } 

तो आप भाग्य से बाहर हैं। कुंजी अद्वितीय हैं।

ऐसा लगता है कि आप जोड़ों की एक सूची चाहते हैं, जैसे { { a, 1 }, { b, 2 }, { a, 5 }, { b, 10 } }। आप अपने आवेदन के आधार पर { a = { 1, 5 }, b = { 2, 10 } } जैसी अंतिम संरचना का भी उपयोग कर सकते हैं।

लेकिन "concatenating" तालिकाओं की धारणा का सरल लुआ टेबल के साथ समझ में नहीं आता है। )

+0

gimf, आप सही थे। मैं टेबल्स में सूचियों के उपयोग की गलत व्याख्या कर रहा था ताकि वे सोच सकें कि उन्हें आसानी से संयोजित किया जा सकता है। आगे के परीक्षण ने मुझे निष्कर्ष निकाला कि मुझे जो करने की ज़रूरत है वह एक विलय था। लुआ नौसिखिया के साथ आपकी मदद और धैर्य के लिए धन्यवाद। –

+1

@ जॉन, हम सभी नए शौक थे ... जटिल भाषाओं से आते हुए, कभी-कभी यह आश्चर्य की बात है कि लुआ की सादगी के अंदर कितनी शक्ति छिप रही है। इसे ग्रोक करने में कुछ समय लग सकता है। "फ़ंक्शन के प्राकृतिक परिणाम ... परिणामों की एक सूची लौटाएं" के लिए धारणा पर – RBerteig

4

आम तौर पर मनमानी तालिकाओं को संयोजित करने की धारणा लुआ में समझ में नहीं आता है क्योंकि एक कुंजी में केवल एक मूल्य हो सकता है।

ऐसे विशेष मामले हैं जिनमें कॉन्सटेनेशन समझ में आता है। ऐसा एक सारणी है जिसमें सरल सरणी होती है, जो परिणाम की सूची लौटने के उद्देश्य से एक फ़ंक्शन का प्राकृतिक परिणाम हो सकती है।

उस मामले में, आप लिख सकते हैं:

 
-- return a new array containing the concatenation of all of its 
-- parameters. Scaler parameters are included in place, and array 
-- parameters have their values shallow-copied to the final array. 
-- Note that userdata and function values are treated as scalar. 
function array_concat(...) 
    local t = {} 
    for n = 1,select("#",...) do 
     local arg = select(n,...) 
     if type(arg)=="table" then 
      for _,v in ipairs(arg) do 
       t[#t+1] = v 
      end 
     else 
      t[#t+1] = arg 
     end 
    end 
    return t 
end 

यह एक उथले प्रतिलिपि है, और जानने के लिए कि एक userdata या समारोह मूल्य एक कंटेनर या किसी तरह के उद्देश्य यह है कि अलग अलग की जरूरत हो सकती है कोई प्रयास करता है उपचार।

एक वैकल्पिक कार्यान्वयन एक नई तालिका बनाने के बजाय पहले तर्क को संशोधित कर सकते हैं। यह प्रतिलिपि बनाने की लागत को बचाएगा, और array_concat स्ट्रिंग पर .. ऑपरेटर से अलग करेगा।

संपादित करें: रूप Joseph Kingry द्वारा एक टिप्पणी में मनाया, मैं ठीक से ... से प्रत्येक तर्क के वास्तविक मूल्य को निकालने में असफल रहा। मैं समारोह से विलय तालिका वापस करने में भी असफल रहा। उत्तर बॉक्स में कोडिंग के लिए मुझे यही मिलता है और कोड का परीक्षण नहीं करता है।

+0

+1। यह काफी संभावना है। – gimpf

+0

मुझे लगता है कि इस फ़ंक्शन में कोई त्रुटि है, मुझे लगता है कि 'for'' के वास्तविक मान को प्राप्त करने के बाद आपको 'अन्य' चुनने की आवश्यकता है। http://lua-users.org/wiki/VarargTheSecondClassCitizen समस्या देखें 8 –

+1

Yup। जाहिर है, मैंने पोस्ट करने से पहले इस कोड का परीक्षण नहीं किया था, या यह दोष स्पष्ट होगा। आखिरी 'अंत' से पहले लापता 'वापसी टी' में हिंडसाइट में अधिक स्पष्ट है। – RBerteig

1

यहां एक कार्यान्वयन है जो मैंने आरबीरटेग के ऊपर किया है, लेकिन छिपे हुए पैरामीटर arg का उपयोग कर रहा है जो किसी फ़ंक्शन को तर्कों की एक चर संख्या प्राप्त करने पर उपलब्ध होता है। निजी तौर पर, मुझे लगता है कि यह चयन वाक्यविन्यास बनाम अधिक पठनीय है।

function array_concat(...) 
    local t = {} 

    for i = 1, arg.n do 
     local array = arg[i] 
     if (type(array) == "table") then 
      for j = 1, #array do 
       t[#t+1] = array[j] 
      end 
     else 
      t[#t+1] = array 
     end 
    end 

    return t 
end 
5

एक साथ दो तालिकाओं जोड़ने ऐसा करते हैं

ii=0 
for i=#firsttable, #secondtable+#firsttable do 
    ii=ii+1 
    firsttable[i]=secondtable[ii] 
end 

चर आप के रूप में कोड के क्रम में पहले तालिका के अंत में पर एक दूसरे कहते हैं जोड़ना चाहते थे के रूप में पहली तालिका का उपयोग करें।

  • i तालिका या सूची की प्रारंभ संख्या है।
  • #secondtable+#firsttable क्या पर समाप्त करने के लिए है।

यह पहले दिखने वाली तालिका में जोड़ना चाहते हैं के अंत में शुरू होता है, और इसलिए यह किसी भी आकार मेज या सूची के साथ काम करता है एक for पाश में दूसरी तालिका के अंत में समाप्त होता है।

+0

यह गलत है। आपको i = (# firsttable + 1) से शुरू करना होगा, या आप पहली तालिका में अंतिम तत्व को घुमाएंगे। पहली तालिका खाली होने के मामले में आप पहलेटेबल [0] तक पहुंचने का भी प्रयास करेंगे, लेकिन एरे को लूआ में 1 से शुरू किया गया है। – scravy

24

overcomplicated जवाब ज्यादा?

यहाँ मेरी दिया गया है:

function TableConcat(t1,t2) 
    for i=1,#t2 do 
     t1[#t1+1] = t2[i] 
    end 
    return t1 
end 
+0

'table.insert' के साथ 'ipairs' पुनरावृत्ति' बेहतर नहीं होगा (अधिक पठनीय और/या तेज़)? –

+0

आईपैयर सामान्य से अधिक महंगा है, इसका उपयोग न करने का कारण यह है कि यह तालिका में वस्तुओं के क्रम की गारंटी नहीं देता है। सम्मिलन का उपयोग न करने का कारण यह है कि यह तालिका पर एक मानक इंडेक्स सेट की तुलना में नाटकीय रूप से अधिक महंगा है, क्योंकि सम्मिलन उस दिनचर्या को कॉल करेगा जो तालिका में मानों को उस इंडेक्स से वापस धक्का देता है, जिस पर कोई मूल्य नहीं है [#t +1], नियमित रूप से एक संकलित भाषा पर प्रदर्शन समस्या उत्पन्न होती है, इसमें कोई फर्क नहीं पड़ता है, लेकिन एक व्याख्या की गई भाषा का उपयोग करके, हमें सावधान रहना होगा कि हम कंप्यूटर से हमारे लिए क्या करना चाहते हैं –

+4

मैं क्या करता हूं पता है, 'ipairs' गारंटी आदेश आदेश i = 1' के लिए है ... पहले टी तक [i] == शून्य, नहीं? जो गैर-अपरिवर्तनीय मामलों के लिए 'i = 1, # t' के समान है। फिर भी 'डालने' बनाम इंडेक्सिंग सेट, आप सही हैं - मैंने मापा है और 5-6x प्रदर्शन अंतर –

3

एक आसान तरीका करने के लिए आप क्या चाहते हैं:

local t1 = {1, 2, 3, 4, 5} 
local t2 = {6, 7, 8, 9, 10} 

local t3 = {unpack(t1)} 
for I = 1,#t2 do 
    t3[#t1+I] = t2[I] 
end 
+0

क्यों {{अनपैक (टी 1)} '? क्या मैं इसे 't1' की प्रति बना देता हूं लेकिन सवाल यह है कि जगह पर अपडेट किया गया है? –

+1

@NasBanov उन्होंने पूछा कि कैसे सम्मिलित करना है। जब आप तारों को जोड़ते हैं तो आपको एक नई स्ट्रिंग मिलती है। मुझे लगता है कि वह ऐसा कुछ चाहता था। – warspyking

+1

हम्म, आप शीर्षक में "concatenation" शब्द के बारे में सही हैं। लेकिन सवाल "संलग्न" के बारे में बोलता है, जो एक उत्परिवर्ती है। अभी भी '{unpack (tbl)} 'तालिका को क्लोन करने के लिए एक साफ चाल है - सीमाओं के साथ (1 एम तत्वों की तरह कुछ) –

2

और एक और तरीका है:

for _,v in ipairs(t2) do 
    table.insert(t1, v) 
end 

यह मेरे लिए सबसे लगता है पठनीय एक - यह दूसरी तालिका में पुनरावृत्त करता है और इसके मूल्यों को पहली बार, कहानी के अंत में जोड़ता है। जानना चाहते हैं कि

1

ऊपर स्पष्ट अनुक्रमण [] के लिए गति में यह किरायों यहाँ, शुद्ध पूर्णांक अनुक्रमण तालिकाओं का एक सेट को श्रेणीबद्ध करने के लिए FYI करें मेरी कार्यान्वयन है।

  1. दो तालिकाओं, concat_2tables
  2. एक और पुनरावर्ती क्रिया concatenateTables श्रेणीबद्ध करने के लिए एक समारोह को परिभाषित: unpack द्वारा तालिका सूची अलग हो गए, और concat_2tables फोन table1 और restTableList

    t1 = {1, 2, 3} 
    t2 = {4, 5} 
    t3 = {6} 
    
    concat_2tables = function(table1, table2) 
        len = table.getn(table1) 
        for key, val in pairs(table2)do 
         table1[key+len] = val 
        end 
        return table1 
    end 
    
    concatenateTables = function(tableList) 
        if tableList==nil then 
         return nil 
        elseif table.getn(tableList) == 1 then 
         return tableList[1] 
        else 
         table1 = tableList[1] 
         restTableList = {unpack(tableList, 2)} 
         return concat_2tables(table1, concatenateTables(restTableList)) 
        end 
    end 
    
    tt = {t1, t2, t3} 
    t = concatenateTables(tt) 
    
संबंधित मुद्दे