We help IT Professionals succeed at work.

How to generate a string in my code with more easier way in C#

Hakan
Hakan used Ask the Experts™
on
Hello I'm using below code;

It's splitting according to underscores at the end it removes first and last two items. Then generates tat string again.

Code seems a bit weird to me. Does anyone know are there any more efficient way?

        public static string GetCutForceChannelBaseName(string fullname)
        {
            string[] parseFullName = fullname.Split(new string[] { "_" }, System.StringSplitOptions.None);
            parseFullName = parseFullName.Where(w => w != parseFullName[System.Array.IndexOf(parseFullName, parseFullName.First())]).ToArray();
            parseFullName = parseFullName.Where(w => w != parseFullName[System.Array.IndexOf(parseFullName, parseFullName.Last())]).ToArray();
            parseFullName = parseFullName.Where(w => w != parseFullName[System.Array.IndexOf(parseFullName, parseFullName.Last())]).ToArray();
            string generateName = System.String.Join("_", parseFullName);
            return generateName;
        }

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
ste5anSenior Developer

Commented:
It's splitting according to underscores at the end it removes first and last two items.
Well, while this is a correct describtion, its not precise enough.

The code splits a string and then removes all occurences of the first and last two items. E.g.

namespace ConsoleCS
{
    using System;
    using System.Linq;

    public class Program
    {
        public static void Main(string[] args)
        {
            string test = "a_b_c_d_e_a_b_c";
            Console.WriteLine(GetCutForceChannelBaseName(test));

            Console.WriteLine("\nDone.");
            Console.ReadLine();
        }

        public static string GetCutForceChannelBaseName(string fullname)
        {
            string[] parseFullName = fullname.Split(new string[] { "_" }, StringSplitOptions.None);
            parseFullName = parseFullName.Where(w => w != parseFullName[Array.IndexOf(parseFullName, parseFullName.First())]).ToArray();
            parseFullName = parseFullName.Where(w => w != parseFullName[Array.IndexOf(parseFullName, parseFullName.Last())]).ToArray();
            parseFullName = parseFullName.Where(w => w != parseFullName[Array.IndexOf(parseFullName, parseFullName.Last())]).ToArray();
            string generateName = string.Join("_", parseFullName);
            return generateName;
        }
    }
}

Open in new window

returns d_e. But as First and Last are defined on the mutating intermediate result, this means especially Last is not a fixed value. E.g. using

string test = "a_b_c_d_e_a_b_c_a";

Open in new window

returns also d_e.

Thus the question is imho wrong. It's not about efficiency. The question is:

What is the correct logic?

Author

Commented:
Yes for removing two last items first i remove last and then read that one and again remove last one so at the end i can be able to remove last two one. Yes you're right it's more about logic.
 
parseFullName = parseFullName.Where(w => w != parseFullName[Array.IndexOf(parseFullName, parseFullName.Last())]).ToArray();
parseFullName = parseFullName.Where(w => w != parseFullName[Array.IndexOf(parseFullName, parseFullName.Last())]).ToArray();
ste5anSenior Developer

Commented:
Please confirm that you want the following output for the given samples:

a_b_c_d_e_a_b_c             => d_e
a_b_c_d_e_a_b_c_a           => d_e
a_b_c_d_e_a_b_c_a_a_a_a_a   => d_e
a_b_c_d_e_a_aaaaa_b_c_aaaaa => b_d_e_b
a_b_c_d_e_f_a_b             => c_d_e

Open in new window

The keyword is "all occurances".

Author

Commented:
Hi ste5an,

it's currently doing that:

string test = "a_b_c_d_e_f_g_h";

array = a, b, c, d, e, f, g, h

//Remove first
a, b, c, d, e, f, g, h => b, c, d, e, f, g, h

// Remove last
b, c, d, e, f, g, h  => b, c, d, e, f, g

// Again remove last
b, c, d, e, f, g => b, c, d, e, f


Join with "_"
b_c_d_e_f

and b_c_d_e_f is my target string.
ste5anSenior Developer
Commented:
Correct, but it also does what I have posted above.

And the question about logic means: is the functoin allowed to do that?

Cause there is a difference between "remove the first and last two items only" (1) and "remove all occurences of the first and last two items" (2) and "remove all occurences of the first item, remove all occurences of the last item of the previos step and remove all occurences of the last item of the previos step (3)". The current function does the latter.

Or visualized, what is the correct result:

1) a_b_c_d_a_b => b_c_d
2) a_b_c_d_a_b => c_d
3) a_b_c_d_a_b => c

Open in new window

?

p.s. when you haven't done it already, run the sample..

namespace ConsoleCS
{
    using System;
    using System.Linq;

    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(GetCutForceChannelBaseName("a_b_c_d_a_b"));
            Console.WriteLine(GetCutForceChannelBaseName("a_b_c_d_e_a_b_c_a"));
            Console.WriteLine(GetCutForceChannelBaseName("a_b_c_d_e_a_b_c_a_a_a_a_a"));
            Console.WriteLine(GetCutForceChannelBaseName("a_b_c_d_e_a_aaaaa_b_c_aaaaa"));
            Console.WriteLine(GetCutForceChannelBaseName("a_b_c_d_e_f_a_b"));

            Console.WriteLine("\nDone.");
            Console.ReadLine();
        }

        public static string GetCutForceChannelBaseName(string fullname)
        {
            Console.WriteLine("\tInput:\t" + fullname);
            string[] parseFullName = fullname.Split(new string[] { "_" }, StringSplitOptions.None);
            parseFullName = parseFullName.Where(w => w != parseFullName[Array.IndexOf(parseFullName, parseFullName.First())]).ToArray();
            Console.WriteLine("\tStep1:\t" + string.Join("_", parseFullName));
            parseFullName = parseFullName.Where(w => w != parseFullName[Array.IndexOf(parseFullName, parseFullName.Last())]).ToArray();
            Console.WriteLine("\tStep1:\t" + string.Join("_", parseFullName));
            parseFullName = parseFullName.Where(w => w != parseFullName[Array.IndexOf(parseFullName, parseFullName.Last())]).ToArray();
            Console.WriteLine("\tStep3:\t" + string.Join("_", parseFullName));
            string generateName = string.Join("_", parseFullName);
            return generateName;
        }
    }
}

Open in new window

Commented:
You could really simplify your method by using Skip and Take; e.g. -
using System;
using System.Linq;

namespace EE_Q29167987
{
    class Program
    {
        static void Main(string[] args)
        {
            var test = "a_b_c_d_e_f_g_h";
            Console.WriteLine(GetCutForceChannelBaseName(test));
            Console.ReadLine();
        }

        static string GetCutForceChannelBaseName(string fullName)
        {
            return string.Join("_", fullName.Split('_').Skip(1).Take(fullName.Split('_').Length - 3));
        }
    }
}

Open in new window

Produces the following result -Capture.PNGOf course, we will probably want to ensure that the length of the incoming fullName has at least 3 characters in the split array and return an empty string if it contains less than 3 characters; e.g. -
using System;
using System.Linq;

namespace EE_Q29167987
{
    class Program
    {
        static void Main(string[] args)
        {
            var tests = new[] { "a_b_c_d_e_f_g_h", "a_b_c", "a_b", "a_b_c_d" };
            foreach(var test in tests)
            {
                Console.WriteLine(GetCutForceChannelBaseName(test));
            }
            Console.ReadLine();
        }

        static string GetCutForceChannelBaseName(string fullName)
        {
            return fullName.Split('_').Length >= 3 ? string.Join("_", fullName.Split('_').Skip(1).Take(fullName.Split('_').Length - 3)) : string.Empty;
        }
    }
}

Open in new window

Which now produces the following output -Capture.PNG-saige-
ste5anSenior Developer

Commented:
@saige, that's exactly the reason why I asked for the logic.. Cause yours implements #1 whereas the original code implements #3.

Commented:
@ste5an, understood.  I thought about trying to comment additionally pointing out what you were stating, but your comments were pretty clear to me.  ;)

-saige-