2011-12-19 22 views
15

मैं एक bespoke एप्लिकेशन के लिए एक एक्सेल निर्यातक लिख रहा हूं जिसे मैं बना रहा हूं, और मुझे सी # में LINQ ग्रुपिंग के बारे में एक प्रश्न है।सप्ताह के आधार पर समूह कैसे समूह करें?

असल में, इस नए एक्सेल निर्यातक वर्ग को दो तिथियां दी गई हैं। कक्षा तब इस तिथि सीमा के बीच सभी सामानों को पुनः प्राप्त करती है।

इस निर्यातक के हिस्से के रूप में, मुझे तिथियों को सप्ताहों में समूहित करने और उस सप्ताह के मूल्य प्राप्त करने में सक्षम होना चाहिए। तो उदाहरण के लिए, अगर मुझे 07/12/2011 और 22/12/2011 (डीडी/एमएम/वाई वाई प्रारूप) दिया गया है, तो मुझे उनके बीच सभी सामानों को समूह में हफ्तों (प्रत्येक सप्ताह रविवार से शुरू) में समूहित करने की आवश्यकता है। उपरोक्त तिथियों का उपयोग कर आदर्श परिणाम

Week 1: (consignments between 04/12/2011 and 10/12/2011) 
Week 2: (consignments between 11/12/2011 and 17/12/2011) 
Week 3: (consignments between 18/11/2011 and 24/12/2011) 

कोई विचार?

उत्तर

28

यहां मूलभूत सवाल यह है कि DateTime उदाहरण को वर्ष के एक सप्ताह में कैसे प्रोजेक्ट करना है। यह Calendar.GetWeekOfYear पर कॉल करके उपयोग किया जा सकता है।

Func<DateTime, int> weekProjector = 
    d => CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(
     d, 
     CalendarWeekRule.FirstFourDayWeek, 
     DayOfWeek.Sunday); 

आप वास्तव में कॉन्फ़िगर कर सकते हैं कि कैसे "सप्ताह के नंबर" विधि कॉल में पैरामीटर अदल-बदल करके निर्धारित किया जाता है: तो प्रक्षेपण परिभाषित करते हैं। आप प्रोजेक्शन को उदा। परिभाषित करने का भी निर्णय ले सकते हैं यदि आप चाहें तो एक विस्तार विधि; यह कोड के सार को नहीं बदलता है। किसी भी मामले में, आप सप्ताह से तो समूह के लिए तैयार हैं:

var consignmentsByWeek = from con in consignments 
         group con by weekProjector(con.Date); 

आप भी दो विशिष्ट तिथियों के बीच consigments के उत्पादन विवश करने के लिए, बस एक उपयुक्त where खंड जोड़ने चाहते हैं; समूह तर्क बदल नहीं है।

21

हेसिटेंट हालांकि मुझे सम्मानित उत्तर देने वाले के साथ असहमत होना है, मेरा मानना ​​है कि यहां स्वीकृत उत्तर गलत है, और यह मूल रूप से एक सप्ताह के मूल्य के प्रक्षेपण का सवाल नहीं है।

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

न केवल GetWeekOfYear() का उपयोग न केवल कई वर्षों के अंत में सात दिनों से कम समय के समूहों में प्रस्तावित परिणाम के रूप में होगा, लेकिन इससे भी बदतर, क्योंकि GetWeekOfYear() द्वारा समर्थित विभिन्न मानकों को अक्सर एक के पहले दिनों में विभाजित किया जाएगा पिछले वर्ष के आखिरी सप्ताह में, और फिर भी GetWeekOfYear() परिणाम में केवल पूर्णांक सप्ताह सूचकांक होता है जिसमें संबंधित वर्ष के संदर्भ नहीं होते हैं, new { Year = date.Year, weekProjector(date) } या date.Year + "-" + weekProjector(date) द्वारा प्रश्नकर्ता के वर्ष में समूह 1 जनवरी 2011 को क्रिसमस दिवस के माध्यम से समूहित किया जाएगा नए साल की पूर्व संध्या बारह महीने बाद उसी वर्ष

तो मैं तर्क था कि मूल प्रश्न मौलिक एक नहीं पेश साल मूल्य के एक सप्ताह के लिए, लेकिन हर समय मूल्य का एक सप्ताह के है, "सप्ताह शुरू y/एम/डी" आप कहते हैं, इसलिए समूहीकरण केवल सप्ताह के पहले दिन के द्वारा किया जा आवश्यकता है, यानी (यह मानते हुए आप रविवार के लिए डिफ़ॉल्ट के लिए खुश हैं) बस:

group by date.AddDays(-(int)date.DayOfWeek) 
+0

मैं इस सवाल के लिए आया था, क्योंकि मैं पहले से ही कोड है कि बहुत ज्यादा की तरह दिखाई देता था स्वीकृत उत्तर। मुझे यह वही कारण नहीं है जो आप बताते हैं। यह कोड सरल है और दिनों को विभाजित करने का बेहतर काम करता है। धन्यवाद! इसके अलावा, आप इस परिणाम को उस दिन जोड़कर सप्ताह के एक अलग दिन (सोमवार की तरह) का उपयोग करके सेगमेंट कर सकते हैं। – user1304444

+0

मैंने उत्तर में सुझाव (महान उत्तर बीटीडब्ल्यू) को निकटतम अवधि में डेटाटाइम को "स्नैप" करने के लिए संशोधित किया। 'तिथि से समूह। एडडेज़ (((int) दिनांक। डेऑफविक) <4? (- (int) दिनांक। डेऑफविक): (- (int) दिनांक। डेऑफविक + 7))' – g2server

1

इसके अलावा को Jon's जवाब आप पहले की तारीख प्राप्त कर सकते हैं सप्ताह में दिन उस तारीख तक समूह।

सप्ताह में पहले दिन की तारीख प्राप्त करने के लिए। आप इस कोड का उपयोग कर सकते हैं:

public static class DateTimeExtensions 
{ 
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek) 
    { 
     int diff = dt.DayOfWeek - startOfWeek; 
     if (diff < 0) 
     { 
      diff += 7; 
     } 
     return dt.AddDays(-1 * diff).Date; 
    } 
} 

तो आप कर सकते हैं इस तरह सप्ताह के पहले दिनांक के आधार पर समूह:

var consignmentsByWeek = from con in consignments 
         group con by con.Datedate.StartOfWeek(DayOfWeek.Monday); 
संबंधित मुद्दे