C# linq合并多维字符串数组
C# linq to merge multidimentional string array
我正在寻找简单的 LINQ 来解决这个问题:
//Input
string[,] arr = new string[,]
{
{"AA:10/BB:20/CC:30","AA:10/BB:20/CC:30","A:10/BB:20/CC:30"},
{"AA:10/BB:20/CC:30/DD:40","AA:10/BB:20/CC:30","A:10/BB:20/CC:30"},
{"AA:10/BB:20/CC:30","AA:10/BB:20/CC:30","A:10/BB:20/CC:30"},
};
//Expected output
string[] res = new string[]
{
"AA:30/BB:60/CC:90/DD:40","AA:30/BB:60/CC:90","BF:30/INF:30"
};
我尝试过的解决方案。
// input
string[] breakups = new string[]
{
"YQ:50/BF:50/YR:50",
"YQ:50/SR:50",
"YQ:50/BF:50/YR:50",
"XX:10"
};
//code
string test = string.Join("/", breakups
.SelectMany(m => m.Split('/'))
.Select(x => x.Split(':'))
.GroupBy(m => m[0])
.Select(m => string.Format("{0}:{1}", m.Key, m.Sum(g => double.Parse(g[1])))));
//Output
string[] res = new string[]
{
"YQ:150/BF:100/YR:100/SR:50/XX:10"
};
但是如果输入是多维的,我会失败。请指导我解决这个问题
我得到了我喜欢的答案
int columnCount = (arr.Split('@').ToArray()).Select(eac => eac.Split('|')).ToArray()[0].Length;
var rowList = string.Join("|", from res in (arr.Split('@').ToArray()).Select(eac => eac.Split('|')).ToArray().SelectMany(x => x).Select((x, i) => new { V = x, Index = i }).
GroupBy(x => (x.Index + 1) % columnCount).Select(g => g.Select(x => x.V).ToList()).ToList()
select string.Join("/", res
.SelectMany(m => m.Split('/'))
.Select(x => x.Split(':'))
.GroupBy(m => m[0])
.Select(m => string.Format("{0}:{1}", m.Key, m.Sum(g => double.Parse(g[1]))))));
我认为求和的查询有点矫枉过正。我永远不想在这样的事情中寻找错误 ;-) 在这种情况下,传统 解决方案会更合适:
Program
-class:
class Program
{
static void Main(string[] args)
{
// Test data.
string[,] data = new string[,]
{
{ "AA:10/BB:20/CC:30", "AA:10/BB:20/CC:30", "A:10/BB:20/CC:30" },
{ "AA:10/BB:20/CC:30/DD:40" ,"AA:10/BB:20/CC:30", "A:10/BB:20/CC:30" },
{ "AA:10/BB:20/CC:30", "AA:10/BB:20/CC:30", "A:10/BB:20/CC:30" },
};
var result = SumColumns(data);
}
// Loops through columns and sums up the values.
static string[] SumColumns(string[,] data)
{
List<Column> columns = new List<Column>();
for (int i = 0; i < data.GetLength(0); i++)
{
Column column = new Column();
for (int j = 0; j < data.GetLength(1); j++)
{
column.Add(data[j, i]);
}
columns.Add(column);
}
// Convert all columns back into strings.
return columns.Select(x => x.ToString()).ToArray();
}
}
Column
-class 汇总值:
class Column
{
Dictionary<string, int> sums = new Dictionary<string, int>();
public void Add(string data)
{
// First split on '/'.
var dataSplitted = data.Split('/');
foreach (var item in dataSplitted)
{
// Second split on ':'.
var itemSplitted = item.Split(':');
string name = itemSplitted[0];
// Try to get the last sum and add the current value:
int sum = 0;
sums.TryGetValue(name, out sum );
sums[name] = sum + int.Parse(itemSplitted[1]);
}
}
// Creates a string from the sums.
public override string ToString()
{
return
sums
.Select(kvp => string.Format("{0}:{1}", kvp.Key, kvp.Value))
.Aggregate((result, next) => result + "/" + next);
}
}
我正在寻找简单的 LINQ 来解决这个问题:
//Input
string[,] arr = new string[,]
{
{"AA:10/BB:20/CC:30","AA:10/BB:20/CC:30","A:10/BB:20/CC:30"},
{"AA:10/BB:20/CC:30/DD:40","AA:10/BB:20/CC:30","A:10/BB:20/CC:30"},
{"AA:10/BB:20/CC:30","AA:10/BB:20/CC:30","A:10/BB:20/CC:30"},
};
//Expected output
string[] res = new string[]
{
"AA:30/BB:60/CC:90/DD:40","AA:30/BB:60/CC:90","BF:30/INF:30"
};
我尝试过的解决方案。
// input
string[] breakups = new string[]
{
"YQ:50/BF:50/YR:50",
"YQ:50/SR:50",
"YQ:50/BF:50/YR:50",
"XX:10"
};
//code
string test = string.Join("/", breakups
.SelectMany(m => m.Split('/'))
.Select(x => x.Split(':'))
.GroupBy(m => m[0])
.Select(m => string.Format("{0}:{1}", m.Key, m.Sum(g => double.Parse(g[1])))));
//Output
string[] res = new string[]
{
"YQ:150/BF:100/YR:100/SR:50/XX:10"
};
但是如果输入是多维的,我会失败。请指导我解决这个问题
我得到了我喜欢的答案
int columnCount = (arr.Split('@').ToArray()).Select(eac => eac.Split('|')).ToArray()[0].Length;
var rowList = string.Join("|", from res in (arr.Split('@').ToArray()).Select(eac => eac.Split('|')).ToArray().SelectMany(x => x).Select((x, i) => new { V = x, Index = i }).
GroupBy(x => (x.Index + 1) % columnCount).Select(g => g.Select(x => x.V).ToList()).ToList()
select string.Join("/", res
.SelectMany(m => m.Split('/'))
.Select(x => x.Split(':'))
.GroupBy(m => m[0])
.Select(m => string.Format("{0}:{1}", m.Key, m.Sum(g => double.Parse(g[1]))))));
我认为求和的查询有点矫枉过正。我永远不想在这样的事情中寻找错误 ;-) 在这种情况下,传统 解决方案会更合适:
Program
-class:
class Program
{
static void Main(string[] args)
{
// Test data.
string[,] data = new string[,]
{
{ "AA:10/BB:20/CC:30", "AA:10/BB:20/CC:30", "A:10/BB:20/CC:30" },
{ "AA:10/BB:20/CC:30/DD:40" ,"AA:10/BB:20/CC:30", "A:10/BB:20/CC:30" },
{ "AA:10/BB:20/CC:30", "AA:10/BB:20/CC:30", "A:10/BB:20/CC:30" },
};
var result = SumColumns(data);
}
// Loops through columns and sums up the values.
static string[] SumColumns(string[,] data)
{
List<Column> columns = new List<Column>();
for (int i = 0; i < data.GetLength(0); i++)
{
Column column = new Column();
for (int j = 0; j < data.GetLength(1); j++)
{
column.Add(data[j, i]);
}
columns.Add(column);
}
// Convert all columns back into strings.
return columns.Select(x => x.ToString()).ToArray();
}
}
Column
-class 汇总值:
class Column
{
Dictionary<string, int> sums = new Dictionary<string, int>();
public void Add(string data)
{
// First split on '/'.
var dataSplitted = data.Split('/');
foreach (var item in dataSplitted)
{
// Second split on ':'.
var itemSplitted = item.Split(':');
string name = itemSplitted[0];
// Try to get the last sum and add the current value:
int sum = 0;
sums.TryGetValue(name, out sum );
sums[name] = sum + int.Parse(itemSplitted[1]);
}
}
// Creates a string from the sums.
public override string ToString()
{
return
sums
.Select(kvp => string.Format("{0}:{1}", kvp.Key, kvp.Value))
.Aggregate((result, next) => result + "/" + next);
}
}