简体   繁体   English

拆分输入字符串并形成逗号分隔的输出

[英]Split input string and form comma separated outputs

We have an input string with several dots separated values and each of these units is separated by space.我们有一个输入字符串,其中有几个点分隔的值,每个单元都用空格分隔。 If the input is like:如果输入是这样的:

string input = "1.2 3.4 5.6 7.8 9", we need to break it as: string input = "1.2 3.4 5.6 7.8 9",我们需要把它分解为:

string beforeDots="1,3,5,7,9" // all ints before the dot. string beforeDots="1,3,5,7,9" // 点之前的所有整数。

string afterDots="2,4,6,8" // all ints after the dot. string afterDots="2,4,6,8" // 点后的所有整数。

We have tried this by:我们已经通过以下方式尝试过:

string inputSplit=input.Split(' ');
string beforeDots=string.Empty;
string afterDots=string.Empty;
foreach (string input in inputSplit)
{
   if (input.IndexOf(".") > 0)
      afterDots += "," + s.Split('.')[1];
   else
      beforeDots += "," + s;
}

if(afterDots.Length > 0)
   afterDots = afterDots.Substring(1, afterDots.Length - 1);

if(beforeDots.Length > 0)
   beforeDots = beforeDots.Substring(1, beforeDots.Length - 1);

Is there any better way to solve this either by linq or by some easier logic?有没有更好的方法可以通过 linq 或一些更简单的逻辑来解决这个问题?

You could clean your logic up a little bit:你可以稍微清理一下你的逻辑:

string input = "1.2 3.4 5.6 7.8 9";

List<string> beforeDot = new List<string>();
List<string> afterDot = new List<string>();

foreach(string s in input.Split())
{
    var split = s.Split('.');

    beforeDot.Add(split[0]);

    if(split.Length == 2)
    {               
        afterDot.Add(split[1]);
    }
}

string beforeDots = string.Join(", ", beforeDot);
string afterDots = string.Join(", ", afterDot);

This gives you the added benefit of having the numbers preserved individually (beforeDot, afterDot) if you need to use it for other logic.如果您需要将其用于其他逻辑,这将为您提供单独保留数字(beforeDot、afterDot)的额外好处。

There really isn't any need to use LINQ here.这里真的没有必要使用 LINQ。

Fiddle here在这里摆弄

I suggest splitting the string, and then using linq.我建议拆分字符串,然后使用 linq。

Edit: I missed the space between number before, the updated method below will work with the spaces taken into account.编辑:我之前错过了数字之间的空格,下面更新的方法将与考虑的空格一起使用。

string input = "1.2 3.4 5.6 7.8 9";
//split, assign index, flatten, group by index.
var inputGroups = input.Split(' ').Select(x => x.Split('.')).Select(x=>x.Select((number, i)=>new { Number = number, Index = i })).SelectMany(x=>x).GroupBy(x=>x.Index);
//group with index 0 was before the dot
var beforeDot= inputGroups.Where(grp=>grp.Key == 0) .FirstOrDefault().Select(x=>x.Number);
//group with key 1 was after the dot
var afterDot= inputGroups.Where(x=>x.Key == 1).FirstOrDefault().Select(x => x.Number);

//then use string.Join(",", str);
var commaSeparatedBefore = string.Join(",",beforeDot);
var commaSeparatedAfter = string.Join(",", afterDot);

You can generalize this for any T with extremely simple and mantainable code without using linq:您可以在不使用 linq 的情况下使用极其简单且可维护的代码将其概括为任何T

public static (IEnumerable<T> Prefixes, IEnumerable<T> suffixes)
    Separate<T>(this IEnumerable<T> source, T splitOn, T resetOn)
{
    if (source == null)
        throw new ArgumentNullException(nameof(source));

    var isSuffix = false;
    var prefixes = new List<T>();
    var suffixes = new List<T>();

    foreach (var c in source)
    {
        if (c.Equals(splitOn))
        {
            isSuffix = true;
        }
        else if (c.Equals(resetOn))
        {
            isSuffix = false;
        }
        else
        {
            if (isSuffix)
            {
                suffixes.Add(c);
            }
            else
            {
                prefixes.Add(c);
            }
        }
    }

    return (prefixes, suffixes);
}

And usage is rather straightforward:用法相当简单:

var res = "1.2 3.4 5.6 7.8 9".Separate('.', ' ');

The output is strings (which can be parsed after the fact):输出是字符串(可以在事后解析):

class Program
{
    static void Main(string[] args)
    {
        var input = "1.2 3.4 5.6 7.8 9";

        var pairs = input.Split(' ').Select(
            s =>
            {
                var split = s.Split('.');

                return new KeyValuePair<string,string>(split[0],split.Length > 1 ? split[1] : null);
            });

        Console.WriteLine(String.Join(",", pairs.Select(p => p.Key)));
        Console.WriteLine(String.Join(",", pairs.Where(p=>p.Value != null).Select(p => p.Value)));

        Console.ReadKey();
    }
}

You, guys, are overcomplicating this.伙计们,你们把这个事情复杂化了。 All in all, these are just decimal numbers.总而言之,这些只是十进制数。 So I'll do this:所以我会这样做:

static void Main(string[] args)
{
    var input = "1.2 3.4 5.6 7.8 9";
    var numbers = input.Split().Select(s => decimal.Parse(s));

    var beforeDots = numbers.Select(n => (int)Math.Truncate(n));
    var afterDots = numbers.Select(n => (int)((n - Math.Truncate(n)) * 10));

    Console.WriteLine(string.Join(",", beforeDots));
    Console.WriteLine(string.Join(",", afterDots));

    Console.ReadLine();
}

// Output:
// 1,3,5,7,9
// 2,4,6,8,0

You can do this:你可以这样做:

var tmp = input.Split(' ').Select(x => x.Split('.'));
var beforeDots = string.Join(",", tmp.Select(x => x.First()));
var afterDots = string.Join(",", tmp.Select(x => x.ElementAtOrDefault(1)).Where(x => x != null));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM