कैसे। में एक चरित्र को अलग स्ट्रिंग में int [] में शामिल होने के लिए?


101

मेरे पास एक पूर्णांक है:

int[] number = new int[] { 2,3,6,7 };

इन्हें एकल स्ट्रिंग में परिवर्तित करने का सबसे आसान तरीका क्या है जहाँ संख्याओं को एक वर्ण द्वारा अलग किया जाता है (जैसे: "2,3,6,7" :)?

मैं C # और .NET 3.5 में हूं।


3
एसओ चट्टानों! मुझे रविवार को 10 मिनट के भीतर ये 3 उत्कृष्ट उत्तर मिल गए!
रिरी

4
चूंकि .NET 4.0ऐसी विधियाँ हैं जो वस्तुओं की एक सरणी लेती हैं और एक IEnumerable ताकि आप बस कर सकें string.join(",", number)। मुझे पता है कि प्रश्न .NET 3.5 निर्दिष्ट करता है, इसलिए मैंने इसका उत्तर नहीं दिया, लेकिन यह उन खोजों में आता है जो किसी संस्करण को निर्दिष्ट नहीं करते हैं और 4.0 में यह जानना किसी की मदद कर सकता है।
जेसन गोएमाट

जवाबों:


162
var ints = new int[] {1, 2, 3, 4, 5};
var result = string.Join(",", ints.Select(x => x.ToString()).ToArray());
Console.WriteLine(result); // prints "1,2,3,4,5"

संपादित करें : (कम से कम) .NET 4.5,

var result = string.Join(",", ints.Select(x => x.ToString()).ToArray());

के बराबर है:

var result = string.Join(",", ints);

संपादित करें :

मुझे StringBuilder के उपयोग के कई समाधान दिखाई देते हैं। किसी विधि से जुड़ने की शिकायतों के लिए IEnumerable तर्क लेना चाहिए।

मैं आपको निराश करने जा रहा हूं :) String.Join को एक ही कारण - प्रदर्शन के लिए सरणी की आवश्यकता है। जुड़ने की विधि को स्मृति की आवश्यक मात्रा को प्रभावी ढंग से प्रचारित करने के लिए डेटा के आकार को जानने की आवश्यकता है।

यहाँ String.Join विधि के आंतरिक कार्यान्वयन का एक हिस्सा है:

// length computed from length of items in input array and length of separator
string str = FastAllocateString(length);
fixed (char* chRef = &str.m_firstChar) // note than we use direct memory access here
{
    UnSafeCharBuffer buffer = new UnSafeCharBuffer(chRef, length);
    buffer.AppendString(value[startIndex]);
    for (int j = startIndex + 1; j <= num2; j++)
    {
        buffer.AppendString(separator);
        buffer.AppendString(value[j]);
    }
}

मैं सुझाए गए तरीकों के प्रदर्शन की तुलना करने के लिए बहुत आलसी हूं। लेकिन मुझे कुछ कहता है कि ज्वाइन करो जीतो :)


यह कोर .NET एक्सटेंशन विधियों का उपयोग करके संभवतः सबसे अच्छा दांव है, लेकिन मैंने वास्तव में स्ट्रिंग की कामना की थी। जॉइन () एक एअन्युमरेबल <string> को ToArray () रूपांतरण से बचने के लिए स्वीकार करेगा।
स्पॉल्सन

कुछ भी अतिभारित स्ट्रिंग से किसी को नहीं रोकता है। एक IEnumerable, साथ ही लेने के लिए। ;)
रॉबर्ट पी

1
यह शायद सबसे आसान समाधान भी है, और केवल सबसे तेज़ नहीं है।
डेव वान डेन आईंड

9
.NET 4 एक String.Join अधिभार प्रदान करता है जो IEnumerable को एक पैरामीटर के रूप में स्वीकार करता है। msdn.microsoft.com/en-us/library/dd783876.aspx
रयान कोह्न

using System.Linq;आवश्यक है।
गायन वीरकुट्टी

32

हालाँकि OP ने .NET 3.5 को निर्दिष्ट किया है, लेकिन C # 2 के साथ .NET 2.0 में ऐसा करने के इच्छुक लोग यह कर सकते हैं:

string.Join(",", Array.ConvertAll<int, String>(ints, Convert.ToString));

मुझे लगता है कि ऐसे कई मामले हैं जहां Convert.xxx फ़ंक्शंस का उपयोग एक लैम्ब्डा के लिए एक वैकल्पिक विकल्प है, हालांकि C # 3 में लैम्बडा टाइप-हीनता की मदद कर सकता है।

एक काफी कॉम्पैक्ट सी # 3 संस्करण जो .NET 2.0 के साथ काम करता है वह यह है:

string.Join(",", Array.ConvertAll(ints, item => item.ToString()))

11

दो दृष्टिकोणों में से एक मिश्रण IEnumerable <T> पर एक विस्तार विधि लिखना होगा जिसमें StringBuilder का उपयोग किया गया था। यहां एक उदाहरण है, अलग-अलग अधिभार के साथ, इस पर निर्भर करता है कि आप परिवर्तन को निर्दिष्ट करना चाहते हैं या सिर्फ सादे तारे पर निर्भर हैं। मैंने अन्य प्रकार के Join के साथ भ्रम से बचने के लिए "Join" के बजाय "JoinStrings" विधि का नाम दिया है। शायद कोई बेहतर नाम लेकर आ सकता है :)

using System;
using System.Collections.Generic;
using System.Text;

public static class Extensions
{
    public static string JoinStrings<T>(this IEnumerable<T> source, 
                                        Func<T, string> projection, string separator)
    {
        StringBuilder builder = new StringBuilder();
        bool first = true;
        foreach (T element in source)
        {
            if (first)
            {
                first = false;
            }
            else
            {
                builder.Append(separator);
            }
            builder.Append(projection(element));
        }
        return builder.ToString();
    }

    public static string JoinStrings<T>(this IEnumerable<T> source, string separator)
    {
        return JoinStrings(source, t => t.ToString(), separator);
    }
}

class Test
{

    public static void Main()
    {
        int[] x = {1, 2, 3, 4, 5, 10, 11};

        Console.WriteLine(x.JoinStrings(";"));
        Console.WriteLine(x.JoinStrings(i => i.ToString("X"), ","));
    }
}

अच्छा समाधान! आपको प्रोजेक्शन पैरामीटर की आवश्यकता नहीं है, हालांकि, आप सिर्फ x.Select (i => i.ToString ("" ") लिख सकते हैं। JoinStrings ("; ") जो अधिक मुहावरेदार है।
जैक्सबी सिप

हां, मैंने उसके बारे में बाद में सोचा। कभी-कभी यह सब एक ही बार में निर्दिष्ट करने में सक्षम होने के लिए अच्छा है, लेकिन संचालन को विभाजित करने के लिए यह निश्चित रूप से अधिक सुरुचिपूर्ण है :)
जॉन स्कीट

8
String.Join(";", number.Select(item => item.ToString()).ToArray());

हमें इसमें Stringशामिल होने से पहले प्रत्येक आइटम को बदलना होगा, इसलिए यह उपयोग करने के लिए समझ में आता है Selectऔर एक लंबोदर अभिव्यक्ति है। यह mapकुछ अन्य भाषाओं के बराबर है । फिर हमें स्ट्रिंग के परिणामस्वरूप संग्रह को वापस सरणी में बदलना होगा, क्योंकिString.Join केवल एक स्ट्रिंग सरणी को स्वीकार करता है।

ToArray()मुझे लगता है कि थोड़ा बदसूरत है। String.Joinवास्तव में स्वीकार करना चाहिए IEnumerable<String>, केवल सरणियों तक इसे सीमित करने का कोई कारण नहीं है। यह शायद सिर्फ इसलिए Joinहै क्योंकि जेनेरिक से पहले है, जब सरणियाँ केवल टाइप किए गए संग्रह उपलब्ध थे।


5

यदि आपके पूर्णांक की सरणी बड़ी हो सकती है, तो आपको स्ट्रिंगब्यूलर का उपयोग करके बेहतर प्रदर्शन मिलेगा। उदाहरण के लिए:

StringBuilder builder = new StringBuilder();
char separator = ',';
foreach(int value in integerArray)
{
    if (builder.Length > 0) builder.Append(separator);
    builder.Append(value);
}
string result = builder.ToString();

संपादित करें: जब मैंने इसे पोस्ट किया था तो मैं गलत धारणा के तहत था कि "StringBuilder.Append (int value)" आंतरिक रूप से एक स्ट्रिंग ऑब्जेक्ट बनाने के बिना पूर्णांक मान के स्ट्रिंग प्रतिनिधित्व को जोड़ने में कामयाब रहा। यह गलत है: रिफ्लेक्टर के साथ विधि का निरीक्षण करने से पता चलता है कि यह केवल मूल्य को जोड़ता है। StString ()।

इसलिए केवल संभावित प्रदर्शन अंतर यह है कि यह तकनीक एक सरणी निर्माण से बचती है, और कचरा संग्रह के लिए तार को जल्द ही मुक्त कर देती है। व्यवहार में यह किसी भी औसत दर्जे का अंतर नहीं करेगा, इसलिए मैंने इस बेहतर समाधान को उकेरा है ।


क्या आपने इसे तेज़ होने के लिए मापा है? String.Join एक StringBuilder का भी उपयोग करता है।
जैक्सबी

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

OTOH String.Join StringBuilder बफर के आकार का पूर्वाभास करता है इसलिए यह आकार बदलने से बचता है। तो यह और भी तेज हो सकता है भले ही इसके लिए अधिक मेमोरी की आवश्यकता हो।
जैक्सबी

5

प्रश्न "एकल स्ट्रिंग में इनको परिवर्तित करने का सबसे आसान तरीका है जहाँ संख्या को वर्ण द्वारा अलग किया जाता है"।

सबसे आसान तरीका है:

int[] numbers = new int[] { 2,3,6,7 };
string number_string = string.Join(",", numbers);
// do whatever you want with your exciting new number string

संपादित करें: यह केवल .NET 4.0+ में काम करता है, मैंने पहली बार .NET 3.5 की आवश्यकता को याद किया जब मैंने प्रश्न पढ़ा।


यह स्ट्रिंग के रूप में मान्य नहीं है। केवल विधि स्ट्रिंग की एक सरणी लेता है। यहाँ एक नज़र है msdn.microsoft.com/en-us/library/tk0xe5h0.aspx
ppolyzos

1
यह एक अतिभारित विधि है: msdn.microsoft.com/en-us/library/dd988350 मैंने अभी-अभी जो कोड लिखा था उसे एक नए कंसोल ऐप में कॉपी किया, एक Console.WriteLine जोड़ा और यह आउटपुट है: 2,335,7,7,7
WebMasterP

1
मुझे लगता है कि यह केवल .net 4 में उपलब्ध है
गोविंद मालवीय

ऑब्जेक्ट सरणी (या स्ट्रिंग सरणी) की आवश्यकता होती है, एक इंट सरणी नहीं। "कॉल अस्पष्ट है" त्रुटि देगा।
लैरीबड

2

मैं पठनीयता और स्थिरता के लिए लंबोदर अभिव्यक्ति से सहमत हूं, लेकिन यह हमेशा सबसे अच्छा विकल्प नहीं होगा। IEnumerable / ToArray और StringBuilder दोनों दृष्टिकोणों का उपयोग करने के लिए नकारात्मक पक्ष यह है कि उन्हें गतिशील रूप से एक सूची या आइटम या वर्णों को विकसित करना होगा, क्योंकि वे नहीं जानते कि अंतिम स्ट्रिंग के लिए कितनी जगह की आवश्यकता होगी।

यदि दुर्लभ मामला जहां गति संक्षिप्तता से अधिक महत्वपूर्ण है, तो निम्नलिखित अधिक कुशल है।

int[] number = new int[] { 1, 2, 3, 4, 5 };
string[] strings = new string[number.Length];
for (int i = 0; i < number.Length; i++)
  strings[i] = number[i].ToString();
string result = string.Join(",", strings);

2
ints.Aggregate("", ( str, n ) => str +","+ n ).Substring(1);

मुझे भी लगा कि कोई सरल तरीका है। प्रदर्शन के बारे में नहीं पता, किसी को भी (सैद्धांतिक) विचार है?


यह समाधान आपको ", 1,2,3,4,5" देगा।
सरीन

धन्यवाद, मैंने इसे Substring(1)ठीक करने के लिए जोड़ा है (यह मेमोरी से था)।
शून्य

2

.NET 4.0 में, स्ट्रिंग जॉइन के लिए एक अधिभार है params object[], इसलिए यह उतना ही सरल है:

int[] ids = new int[] { 1, 2, 3 };
string.Join(",", ids);

उदाहरण

int[] ids = new int[] { 1, 2, 3 };
System.Data.Common.DbCommand cmd = new System.Data.SqlClient.SqlCommand("SELECT * FROM some_table WHERE id_column IN (@bla)");
cmd.CommandText = cmd.CommandText.Replace("@bla",  string.Join(",", ids));

.NET 2.0 में, यह थोड़ा अधिक कठिन है, क्योंकि ऐसा कोई अधिभार नहीं है। तो आपको अपनी स्वयं की सामान्य विधि चाहिए:

public static string JoinArray<T>(string separator, T[] inputTypeArray)
{
    string strRetValue = null;
    System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();

    for (int i = 0; i < inputTypeArray.Length; ++i)
    {
        string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture);

        if (!string.IsNullOrEmpty(str))
        { 
            // SQL-Escape
            // if (typeof(T) == typeof(string))
            //    str = str.Replace("'", "''");

            ls.Add(str);
        } // End if (!string.IsNullOrEmpty(str))

    } // Next i 

    strRetValue= string.Join(separator, ls.ToArray());
    ls.Clear();
    ls = null;

    return strRetValue;
}

.NET 3.5 में, आप एक्सटेंशन विधियों का उपयोग कर सकते हैं:

public static class ArrayEx
{

    public static string JoinArray<T>(this T[] inputTypeArray, string separator)
    {
        string strRetValue = null;
        System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();

        for (int i = 0; i < inputTypeArray.Length; ++i)
        {
            string str = System.Convert.ToString(inputTypeArray[i], System.Globalization.CultureInfo.InvariantCulture);

            if (!string.IsNullOrEmpty(str))
            { 
                // SQL-Escape
                // if (typeof(T) == typeof(string))
                //    str = str.Replace("'", "''");

                ls.Add(str);
            } // End if (!string.IsNullOrEmpty(str))

        } // Next i 

        strRetValue= string.Join(separator, ls.ToArray());
        ls.Clear();
        ls = null;

        return strRetValue;
    }

}

तो आप JoinArray एक्सटेंशन-मेथड का उपयोग कर सकते हैं।

int[] ids = new int[] { 1, 2, 3 };
string strIdList = ids.JoinArray(",");

यदि आप एक्सटेंशन को अपने कोड में जोड़ते हैं, तो आप उस एक्सटेंशन विधि का उपयोग .NET 2.0 में भी कर सकते हैं:

// you need this once (only), and it must be in this namespace
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute {}
}

1

8
इसके लिए लिंक किए गए पृष्ठ पर परिभाषित विस्तार विधि की आवश्यकता होती है, यह स्पष्ट हो सकता है
StocksR
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.