दिलचस्प पोस्ट
क्या जावा कोड से चींटी या एनएसआईएस स्क्रिप्ट को कॉल करना संभव है? जर्सी – कैसे सेवा नकली करने के लिए मैं पायथन में निरंतर कैसे बना सकता हूं? जब यह एक नई लाइन पढ़ता है, तो स्कैनफ़ को छोड़ दें? डीजेएगो मॉडल में सीएसवी डेटा कैसे आयात करें ऑब्जेक्ट का विस्तार। प्रोटोटाइप जावास्क्रिप्ट कोणीय 2 ड्रॉपडाउन विकल्प डिफ़ॉल्ट मूल्य संदर्भ – इस regex क्या मतलब है? जीजीप्लॉट भूखंडों को समान एक्स-अक्ष की चौड़ाई और डॉट प्लॉट पंक्तियों के बीच एक ही जगह सेट करें सीएसएस पहचानकर्ताओं के लिए अनुमत वर्ण C # में DateTime के लिए स्ट्रिंग पार्स करें आर में एक। Csv फ़ाइल को पढ़ने की कोशिश करते समय 'अपूर्ण अंतिम पंक्ति' चेतावनी सी / सी ++ बहुआयामी सरणी इंटरनेशनल संख्याओं के एक सरणी से न्यूनतम या अधिकतम मूल्य प्राप्त करने का सबसे अच्छा तरीका क्या है? संप्रभु और असली दुनिया उदाहरण contravariance

मौजूदा सरणी से उप-सरणी प्राप्त करना

मेरे पास 10 तत्वों का सरणी एक्स है मैं एक नया सरणी बनाना चाहूंगा जिसमें एक्स के सभी तत्व शामिल होंगे जो इंडेक्स 3 से शुरू हो और इंडेक्स 7 में समाप्त हो जाए। सुनिश्चित करें कि मैं आसानी से एक लूप लिख सकता हूं जो मेरे लिए यह करेंगे, लेकिन मैं अपने कोड को जितना संभव हो सके रखना चाहूंगा । क्या सी # में कोई तरीका है जो यह मेरे लिए कर सकता है?

कुछ ऐसा (छद्म कोड):

Array NewArray = oldArray.createNewArrayFromRange(int BeginIndex , int EndIndex) 

Array.Copy मेरी आवश्यकताओं के अनुरूप नहीं है मुझे क्लोन होने के लिए नए सरणी में वस्तुओं की ज़रूरत है Array.copy सिर्फ एक सी-शैली memcpy बराबर है, यह नहीं है कि मैं क्या देख रहा हूँ।

वेब के समाधान से एकत्रित समाधान "मौजूदा सरणी से उप-सरणी प्राप्त करना"

आप इसे एक एक्सटेंशन विधि के रूप में जोड़ सकते हैं:

 public static T[] SubArray<T>(this T[] data, int index, int length) { T[] result = new T[length]; Array.Copy(data, index, result, 0, length); return result; } static void Main() { int[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int[] sub = data.SubArray(3, 4); // contains {3,4,5,6} } 

पुनः क्लोनिंग अपडेट करें (जो मूल प्रश्न में स्पष्ट नहीं था)। यदि आप वास्तव में एक गहरे क्लोन चाहते हैं; कुछ इस तरह:

 public static T[] SubArrayDeepClone<T>(this T[] data, int index, int length) { T[] arrCopy = new T[length]; Array.Copy(data, index, arrCopy, 0, length); using (MemoryStream ms = new MemoryStream()) { var bf = new BinaryFormatter(); bf.Serialize(ms, arrCopy); ms.Position = 0; return (T[])bf.Deserialize(ms); } } 

यह ऑब्जेक्ट सीरियलाइज करने योग्य ( [Serializable] या ISerializable ), यद्यपि। आप आसानी से किसी भी अन्य सीरियललाइज़र के लिए विकल्प चुन सकते हैं- XmlSerializer DataContractSerializer , डाटा DataContractSerializer , प्रोटोबुफ़-नेट आदि।

ध्यान दें कि डायरेक्ट क्लोन सीरियलाइजेशन के बिना मुश्किल है; विशेष रूप से, ICloneable ज्यादातर मामलों में विश्वास करना मुश्किल है

आप ऐरे का उपयोग कर सकते हैं। Array.Copy(...) इसे बनाने के बाद नई सरणी में प्रतिलिपि बनाने के लिए, लेकिन मुझे नहीं लगता कि कोई ऐसा तरीका है जो नई सरणी बनाता है और कई तत्वों की प्रतियां करता है

यदि आप .NET 3.5 का उपयोग कर रहे हैं तो आप LINQ का उपयोग कर सकते हैं:

 var newArray = array.Skip(3).Take(5).ToArray(); 

लेकिन यह कुछ कम कुशल होगा

अधिक विशिष्ट स्थितियों के लिए विकल्पों के लिए इसी तरह के प्रश्न का उत्तर देखें।

क्या आपने ArraySegment उपयोग करने पर विचार किया है?

http://msdn.microsoft.com/en-us/library/1hsbd92d.aspx

मुझे लगता है कि आप केवल क्लोनिंग करना चाहते हैं, न केवल संदर्भ कॉपी करना इस मामले में आप उपयोग कर सकते हैं। प्रोजेक्ट सरणी के सदस्यों को उनके क्लोन में चुनें। उदाहरण के लिए, यदि आपके तत्वों को आईक्लनेबल लागू किया जाता है तो आप ऐसा कुछ कर सकते हैं:

 var newArray = array.Skip(3).Take(5).Select(eachElement => eachElement.Clone()).ToArray(); 

निम्न कोड एक पंक्ति में करता है:

 // Source array string[] Source = new string[] { "A", "B", "C", "D" }; // Extracting a slice into another array string[] Slice = new List<string>(Source).GetRange(2, 2).ToArray(); 

मार्क के उत्तर पर बिल्डिंग लेकिन वांछित क्लोनिंग व्यवहार को जोड़ना

 public static T[] CloneSubArray<T>(this T[] data, int index, int length) where T : ICloneable { T[] result = new T[length]; for (int i = 0; i < length; i++) { var original = data[index + i]; if (original != null) result[i] = (T)original.Clone(); return result; } 

और अगर आईसीलाइएबल को कार्यान्वित करना मुश्किल है तो हार्वर्ड स्ट्रैंडेन की कॉपीबल लाइब्रेरी का उपयोग करके एक चिंतनशील चीज की आवश्यकता होती है ताकि भारी भार उठाने की आवश्यकता हो।

 using OX.Copyable; public static T[] DeepCopySubArray<T>( this T[] data, int index, int length) { T[] result = new T[length]; for (int i = 0; i < length; i++) { var original = data[index + i]; if (original != null) result[i] = (T)original.Copy(); return result; } 

ध्यान दें कि ओएक्स। काटेबल कार्यान्वयन किसी भी साथ काम करता है:

स्वचालित प्रतिलिपि के लिए काम करने के लिए, हालांकि, निम्न बयानों में से एक को उदाहरण के लिए रखना चाहिए:

  • इसके प्रकार में एक पैरामीलेटेड कन्स्ट्रक्टर होना चाहिए, या
  • यह एक प्रतिलिपि होना चाहिए, या
  • इसमें इसके प्रकार के लिए एक IInstanceProvider पंजीकृत होना आवश्यक है।

तो यह आपके पास लगभग किसी भी स्थिति को कवर करना चाहिए। यदि आप ऑब्जेक्ट्स क्लोनिंग कर रहे हैं जहां उप ग्राफ़ में डीबी कनेक्शन या फाइल / स्ट्रीम जैसी चीज़ें हैं, तो आपके पास स्पष्ट रूप से समस्याएं हैं लेकिन यह किसी भी सामान्यीकृत गहरी कॉपी के लिए सही है।

यदि आप किसी अन्य गहरी प्रतिलिपि दृष्टिकोण का उपयोग करना चाहते हैं, तो यह लेख कई अन्य लोगों को सूचीबद्ध करता है, इसलिए मैं खुद को लिखने की कोशिश नहीं करने का सुझाव दूंगा।

 string[] arr = { "Parrot" , "Snake" ,"Rabbit" , "Dog" , "cat" }; arr = arr.ToList().GetRange(0, arr.Length -1).ToArray(); 

आप इसे काफी आसानी से कर सकते हैं;

  object[] foo = new object[10]; object[] bar = new object[7]; Array.Copy(foo, 3, bar, 0, 7); 

Array.ConstrainedCopy काम करेगा।

 public static void ConstrainedCopy ( Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length ) 

मुझे लगता है कि जो कोड आप देख रहे हैं वह है:

Array.Copy(oldArray, 0, newArray, BeginIndex, EndIndex - BeginIndex)

डेटा की प्रतिलिपि बनाने के विकल्प के रूप में आप आवरण बना सकते हैं जो आपको मूल सरणी के एक हिस्से तक पहुँच देता है जैसे कि यह सरणी के हिस्से की एक प्रति है। लाभ यह है कि आप स्मृति में डेटा की एक दूसरी प्रति प्राप्त नहीं करते हैं, और डेटा तक पहुंचने पर दोष थोड़ी सी ओवरहेड है।

 public class SubArray<T> : IEnumerable<T> { private T[] _original; private int _start; public SubArray(T[] original, int start, int len) { _original = original; _start = start; Length = len; } public T this[int index] { get { if (index < 0 || index >= Length) throw new IndexOutOfRangeException(); return _original[_start + index]; } } public int Length { get; private set; } public IEnumerator<T> GetEnumerator() { for (int i = 0; i < Length; i++) { yield return _original[_start + i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } 

उपयोग:

 int[] original = { 1, 2, 3, 4, 5 }; SubArray<int> copy = new SubArray<int>(original, 2, 2); Console.WriteLine(copy.Length); // shows: 2 Console.WriteLine(copy[0]); // shows: 3 foreach (int i in copy) Console.WriteLine(i); // shows 3 and 4 

कोई भी ऐसा तरीका नहीं है जो आप चाहते हैं। आपको अपने सरणी में कक्षा के लिए एक क्लोन पद्धति उपलब्ध करनी होगी। उसके बाद, यदि LINQ एक विकल्प है:

 Foo[] newArray = oldArray.Skip(3).Take(5).Select(item => item.Clone()).ToArray(); class Foo { public Foo Clone() { return (Foo)MemberwiseClone(); } } 

ऐरे का उपयोग करने के बारे में कैसे। संयोजित कूट :

 int[] ArrayOne = new int[8] {1,2,3,4,5,6,7,8}; int[] ArrayTwo = new int[5]; Array.ConstrainedCopy(ArrayOne, 3, ArrayTwo, 0, 7-3); 

नीचे मेरी मूल पोस्ट है यह काम नहीं करेगा

आप अर्रे का उपयोग कर सकते हैं। कॉपी करें :

 int[] ArrayOne = new int[8] {1,2,3,4,5,6,7,8}; int[] ArrayTwo = new int[5]; ArrayOne.CopyTo(ArrayTwo,3); //starts copy at index=3 until it reaches end of //either array 

इस बारे में कैसा है:

 public T[] CloneCopy(T[] array, int startIndex, int endIndex) where T : ICloneable { T[] retArray = new T[endIndex - startIndex]; for (int i = startIndex; i < endIndex; i++) { array[i - startIndex] = array[i].Clone(); } return retArray; } 

इसके बाद आप उन सभी वर्गों पर आईसीलाइनेबल इंटरफ़ेस को कार्यान्वित करने की ज़रूरत है जिन पर आपको इसकी आवश्यकता है, लेकिन ऐसा करना चाहिए।

मुझे यकीन नहीं है कि यह वास्तव में कितना गहरा है, लेकिन:

MyArray.ToList<TSource>().GetRange(beginningIndex, endIndex).ToArray()

यह थोड़ा सा ओवरहेड है, लेकिन यह एक अनावश्यक विधि काट सकता है

जहां तक ​​क्लोनिंग चला जाता है, मुझे नहीं लगता कि सीरियलाइजेशन आपके कन्स्ट्रक्टर को कॉल करता है। यदि आप ctor की दिलचस्प बातें कर रहे हैं, तो यह क्लास इनवेरिएन्ट को तोड़ सकता है।

ऐसा लगता है कि सुरक्षित शर्त आभासी क्लोन पद्धतियां हैं जो प्रतिलिपि कन्स्ट्रक्टर को कहते हैं।

 protected MyDerivedClass(MyDerivedClass myClass) { ... } public override MyBaseClass Clone() { return new MyDerivedClass(this); } 

सरणी में तत्वों का क्लोनिंग कुछ ऐसा नहीं है जिसे एक सार्वभौमिक तरीके से किया जा सकता है। क्या आप गहरे क्लोनिंग चाहते हैं या सभी सदस्यों की एक साधारण कॉपी?

आइए "सर्वोत्तम प्रयास" दृष्टिकोण के लिए जाएं: ICloneable इंटरफ़ेस या बाइनरी सीरियलाइजेशन का उपयोग करके क्लोनिंग ऑब्जेक्ट्स:

 public static class ArrayExtensions { public static T[] SubArray<T>(this T[] array, int index, int length) { T[] result = new T[length]; for (int i=index;i<length+index && i<array.Length;i++) { if (array[i] is ICloneable) result[i-index] = (T) ((ICloneable)array[i]).Clone(); else result[i-index] = (T) CloneObject(array[i]); } return result; } private static object CloneObject(object obj) { BinaryFormatter formatter = new BinaryFormatter(); using (MemoryStream stream = new MemoryStream()) { formatter.Serialize(stream, obj); stream.Seek(0,SeekOrigin.Begin); return formatter.Deserialize(stream); } } } 

यह सही समाधान नहीं है, क्योंकि कोई भी ऐसा नहीं है जो किसी भी प्रकार के ऑब्जेक्ट के लिए काम करेगा।

आप Microsoft द्वारा बनाई गई कक्षा ले सकते हैं:

 internal class Set<TElement> { private int[] _buckets; private Slot[] _slots; private int _count; private int _freeList; private readonly IEqualityComparer<TElement> _comparer; public Set() : this(null) { } public Set(IEqualityComparer<TElement> comparer) { if (comparer == null) comparer = EqualityComparer<TElement>.Default; _comparer = comparer; _buckets = new int[7]; _slots = new Slot[7]; _freeList = -1; } public bool Add(TElement value) { return !Find(value, true); } public bool Contains(TElement value) { return Find(value, false); } public bool Remove(TElement value) { var hashCode = InternalGetHashCode(value); var index1 = hashCode % _buckets.Length; var index2 = -1; for (var index3 = _buckets[index1] - 1; index3 >= 0; index3 = _slots[index3].Next) { if (_slots[index3].HashCode == hashCode && _comparer.Equals(_slots[index3].Value, value)) { if (index2 < 0) _buckets[index1] = _slots[index3].Next + 1; else _slots[index2].Next = _slots[index3].Next; _slots[index3].HashCode = -1; _slots[index3].Value = default(TElement); _slots[index3].Next = _freeList; _freeList = index3; return true; } index2 = index3; } return false; } private bool Find(TElement value, bool add) { var hashCode = InternalGetHashCode(value); for (var index = _buckets[hashCode % _buckets.Length] - 1; index >= 0; index = _slots[index].Next) { if (_slots[index].HashCode == hashCode && _comparer.Equals(_slots[index].Value, value)) return true; } if (add) { int index1; if (_freeList >= 0) { index1 = _freeList; _freeList = _slots[index1].Next; } else { if (_count == _slots.Length) Resize(); index1 = _count; ++_count; } int index2 = hashCode % _buckets.Length; _slots[index1].HashCode = hashCode; _slots[index1].Value = value; _slots[index1].Next = _buckets[index2] - 1; _buckets[index2] = index1 + 1; } return false; } private void Resize() { var length = checked(_count * 2 + 1); var numArray = new int[length]; var slotArray = new Slot[length]; Array.Copy(_slots, 0, slotArray, 0, _count); for (var index1 = 0; index1 < _count; ++index1) { int index2 = slotArray[index1].HashCode % length; slotArray[index1].Next = numArray[index2] - 1; numArray[index2] = index1 + 1; } _buckets = numArray; _slots = slotArray; } internal int InternalGetHashCode(TElement value) { if (value != null) return _comparer.GetHashCode(value) & int.MaxValue; return 0; } internal struct Slot { internal int HashCode; internal TElement Value; internal int Next; } } 

और फिर

 public static T[] GetSub<T>(this T[] first, T[] second) { var items = IntersectIteratorWithIndex(first, second); if (!items.Any()) return new T[] { }; var index = items.First().Item2; var length = first.Count() - index; var subArray = new T[length]; Array.Copy(first, index, subArray, 0, length); return subArray; } private static IEnumerable<Tuple<T, Int32>> IntersectIteratorWithIndex<T>(IEnumerable<T> first, IEnumerable<T> second) { var firstList = first.ToList(); var set = new Set<T>(); foreach (var i in second) set.Add(i); foreach (var i in firstList) { if (set.Remove(i)) yield return new Tuple<T, Int32>(i, firstList.IndexOf(i)); } } 

यह इष्टतम तरीका है, मैंने पाया, ऐसा करने के लिए:

 private void GetSubArrayThroughArraySegment() { int[] array = { 10, 20, 30 }; ArraySegment<int> segment = new ArraySegment<int>(array, 1, 2); Console.WriteLine("-- Array --"); int[] original = segment.Array; foreach (int value in original) { Console.WriteLine(value); } Console.WriteLine("-- Offset --"); Console.WriteLine(segment.Offset); Console.WriteLine("-- Count --"); Console.WriteLine(segment.Count); Console.WriteLine("-- Range --"); for (int i = segment.Offset; i <= segment.Count; i++) { Console.WriteLine(segment.Array[i]); } } 

आशा करता हूँ की ये काम करेगा!

 public static T[] SubArray<T>(T[] data, int index, int length) { List<T> retVal = new List<T>(); if (data == null || data.Length == 0) return retVal.ToArray(); bool startRead = false; int count = 0; for (int i = 0; i < data.Length; i++) { if (i == index && !startRead) startRead = true; if (startRead) { retVal.Add(data[i]); count++; if (count == length) break; } } return retVal.ToArray(); }