डी

2012-12-27 15 views
5

में किसी सरणी से किसी दिए गए मान की सभी घटनाओं को हटाकर मान लीजिए कि मेरे पास एक सरणी है। मैं उस सरणी के भीतर सभी तत्वों को हटाना चाहता हूं जिनके पास दिया गया मान है। क्या किसी को भी यह करना आता है? जिस मूल्य को मैं निकालने का प्रयास कर रहा हूं वह एक से अधिक बार हो सकता है और सरणी जरूरी नहीं है। मैं एक नई सरणी बनाने के बजाय सरणी को जगह में फ़िल्टर करना पसंद करूंगा। उदाहरण के लिए, [1, 2, 3, 2, 4] से 2 मान को हटाकर [1, 3, 4] परिणाम देना चाहिए।डी

T[] without(T)(T[] stuff, T thingToExclude) { 
    auto length = stuff.length; 
    T[] result; 
    foreach (thing; stuff) { 
     if (thing != thingToExclude) { 
      result ~= thing; 
     } 
    } 
    return result; 
} 

stuff = stuff.without(thingToExclude); 
writeln(stuff); 

यह अनावश्यक रूप से जटिल और अक्षम लगता है:

यह सबसे अच्छी बात मैं के साथ आ सकता है। क्या कोई आसान तरीका है? मैंने मानक लाइब्रेरी में std.algorithm मॉड्यूल को देखा जो कुछ उपयोगी खोजने की उम्मीद कर रहा था, लेकिन जो कुछ भी दिखता था वह वही करेगा जो मैं चाहता था वह समस्याग्रस्त था।

import std.stdio, std.algorithm, std.conv; 

auto stuff = [1, 2, 3, 2, 4]; 
auto thingToExclude = 2; 

/* Works fine with a hard-coded constant but compiler throws an error when 
    given a value unknowable by the compiler: 
    variable thingToExclude cannot be read at compile time */ 
stuff = filter!("a != " ~ to!string(thingToExclude))(stuff); 
writeln(stuff); 

/* Works fine if I pass the result directly to writeln but compiler throws 
    an error if I try assigning it to a variable such as stuff: 
    cannot implicitly convert expression (filter(stuff)) of type FilterResult!(__lambda2,int[]) to int[] */ 
stuff = filter!((a) { return a != thingToExclude; })(stuff); 
writeln(stuff); 

/* Mysterious error from compiler: 
    template to(A...) if (!isRawStaticArray!(A)) cannot be sliced with [] */ 
stuff = to!int[](filter!((a) { return a != thingToExclude; })(stuff)); 
writeln(stuff); 

तो, मैं कैसे एक मूल्य की सभी घटनाओं की एक सरणी से अनुक्रमित उन्हें प्रदर्शित करने वाले को जानने के बिना निकाल सकते हैं: यहाँ सब मैंने कोशिश की है कि काम नहीं किया के कुछ उदाहरण हैं?

+1

आपके अंतिम प्रयास के साथ समस्या ऑपरेटर प्राथमिकता है: 'to! Int []' '(टी)' टेम्पलेट को चालू कर रहा है और फिर '[] ', यानी स्लाइस ऑपरेटर को लागू कर रहा है। यदि आप लक्ष्य प्रकार के हिस्से के रूप में ब्रैकेट चाहते हैं तो आपको माता-पिता की आवश्यकता है: 'to! (Int []) (...)'। यह अभी भी काम नहीं करेगा, लेकिन यह अर्थात् सही है। – scry

उत्तर

9

std.algorithm.filter आप जो चाहते हैं उसके करीब है: आपका दूसरा प्रयास अच्छा है।

आप या तो इसे एक नए चर के लिए असाइन करना चाहते हैं या उस पर सरणी() फ़ंक्शन का उपयोग करना चाहते हैं।

auto stuffWithoutThing = filter!((a) { return a != thingToExclude; })(stuff); 
// use stuffWithoutThing 

या

stuff = array(filter!((a) { return a != thingToExclude; })(stuff)); 

पहले एक एक नई सरणी का निर्माण नहीं करता। यह केवल उस चीज़ पर पुनरावृत्ति प्रदान करता है जो दी गई चीज़ के साथ फ़िल्टर किया जाता है।

दूसरा व्यक्ति सामग्री को पकड़ने के लिए एक नई सरणी के लिए स्मृति आवंटित करेगा। काम करने के लिए आपको std.array मॉड्यूल आयात करना होगा।

+0

मैंने कुछ मामूली सुधार किए हैं, और अब आपकी पोस्ट बिल्कुल बताती है कि मैं क्या करने की कोशिश कर रहा था। धन्यवाद। –

3

आप मूल्यों को निकालना चाहते हैं आप,

auto stuffWithoutThing = remove!((a) { return a == thingToExclude; })(stuff); 

इस एक नई सरणी लेकिन जगह में काम आवंटित नहीं होगा हटाने का उपयोग कर सकते ध्यान दें कि stuff सीमा परिवर्तनशील होने की जरूरत है

+1

आप कहते हैं "यह एक नई सरणी आवंटित नहीं करेगा लेकिन जगह पर काम करेगा"। इससे तुम्हारा क्या मतलब? क्या यह 'सामान' सरणी में परिवर्तन करेगा? यदि ऐसा है, तो 'stuffWithoutThing' को असाइन करने का बिंदु क्या है? –

+0

हाँ यह सामान में परिवर्तन करेगा, असाइन करने का बिंदु यह है कि आप सामान सरणी की नई लंबाई –

+1

मुझे केवल लंबाई जानने के लिए असाइन क्यों करना है? मैं सिर्फ 'सामान' की लंबाई क्यों नहीं देख सकता? –

5

समारोह को फिर से देखें http://dlang.org/phobos/std_algorithm.html में हटाएं। दो रणनीतियों हैं - स्थिर और अस्थिर इस बात पर निर्भर करता है कि क्या आप शेष तत्वों को अपनी सापेक्ष स्थिति रखना चाहते हैं। दोनों रणनीतियों को जगह में संचालित होता है और ओ (एन) जटिलता होती है। अस्थिर संस्करण कम लिखता है।