我有一張桌子:
Name | account info| AccountNumber
-----| ------------| ------
abc | IT | 3000
bdc | Desk | 2000
sed | Kitchen | 3000
afh | work | 4000
hsfs | home | 2000
我想實作這樣的目標:
Name | account info| DisguiseInfo
-----| ------------| ------
abc | IT | Acc1
bdc | Desk | Acc2
sed | Kitchen | Acc1
afh | work | Acc3
hsfs | home | Acc2
我試過這樣做:
int count = 1;
var disguise = listResults.GroupBy(x => x.ID).Select(y =>
y.First()).Distinct();
foreach (var i in disguise)
{
i.DisguiseName = "Acc " count;
count ;
}
這給出了這樣的結果(非常接近我想要的):
Name | account info| DisguiseInfo
-----| ------------| ------
abc | IT | Acc1
bdc | Desk | Acc2
sed | Kitchen |
afh | work | Acc3
hsfs | home |
問題在于,它不能將相同的字串值“Acc1”添加到串列中的相同重復值中,(表的其余部分為空白,只有第一個值被替換),那么如何用匹配的 ID 替換整個值?
//編輯 資料正在使用 sqlcommand 在名為 SQLQuery 的類中填充,在此類中有一個名為 Account 的方法,其執行方式如下:
SqlDataReader reader = command.ExecuteReader();
List<ViewModel> returnList = new List<ViewModel>();
if (reader.HasRows)
{
while (reader.Read())
{
ViewModel vm = new ViewModel();
vm.Name = reader.GetString(2);
vm.AccountInfo= reader.GetString(3);
vm.AccountNumber = reader.GetInt32(4);
returnList.Add(vm)
}
}
所以這個方法回傳上面的第一個表沒有問題。在我的控制器操作中,我可能希望將 SQLQuery 回傳串列復制到另一個串列中進行過濾,所以我正在做(在操作方法中):
public async Task<IActionResult> DisguiseAction(string accNum)
{
List<ViewModel> executeSQL = new List<ViewModel>();
SQLQuery getQuery = new SQLQuery();
executeSQL = getQuery.Account(accNum); //at this point the sql
//gets executed with the correct value. Now I need to disguise the
//value. which I did
int count = 1;
var disguise = listResults.GroupBy(x => x.ID).Select(y =>
y.First()).Distinct();
foreach (var i in disguise)
{
i.DisguiseName = "Acc " count;
count ;
}
}
uj5u.com熱心網友回復:
你的問題是.Distinct()呼叫,它只從每個組中取出第一個元素。由于您需要記住所有已經看到的值,因此使用字典來保存已經映射的值更容易。一種可能是:
var accounts = new List<Account>
{
new Account { Name = "abc", Department = "IT", AccountInfo = 3000 },
new Account { Name = "bdc", Department = "Desk", AccountInfo = 2000 },
new Account { Name = "sed", Department = "Kitchen", AccountInfo = 3000 },
new Account { Name = "afh", Department = "work", AccountInfo = 4000 },
new Account { Name = "hsfs", Department = "home", AccountInfo = 2000 },
};
var mappings = new Dictionary<int, string>();
var summary = accounts
.Select(acc => new AccountSummary
{
Name = acc.Name,
Department = acc.Department,
DisguiseInfo = GetOrAddMapping(acc.AccountInfo, mappings)
})
.ToList();
foreach (var item in summary)
{
Console.WriteLine(JsonSerializer.Serialize(item));
}
在這種情況下,輔助方法將是:
private static string GetOrAddMapping(int accountInfo, Dictionary<int, string> mappings)
{
if (!mappings.TryGetValue(accountInfo, out var value))
{
value = $"Acc{mappings.Count 1}";
mappings.Add(accountInfo, value);
}
return value;
}
uj5u.com熱心網友回復:
using System;
using System.Collections.Generic;
public class Ent
{
public Ent(string a, string b, string c)
{
name = a;
location = b;
id = c;
}
public string name;
public string location;
public string id;
public override string ToString()
{
return $"{name} | {location} | {id}";
}
}
public class Program
{
public static void Main()
{
var input = new List<Ent>
{
new Ent("abc", "IT", "3000"),
new Ent("bcd", "Desk", "2000"),
new Ent("sed", "Kitchen", "3000"),
new Ent("afh", "work", "4000"),
new Ent("hsf", "home", "2000"),
};
var output = input
.GroupBy(x => x.id) // x is of type Ent
.SelectMany(y => // y is of type IGrouping<string, IEnumerable<Ent>>
y.Select(z => // z is of type Ent
new Ent(z.name, z.location, "Acc" y.Key.Substring(0, 1))));
foreach(var line in output)
Console.WriteLine(line);
}
}
給出如下所示的輸出:
abc | IT | Acc3
sed | Kitchen | Acc3
bcd | Desk | Acc2
hsf | home | Acc2
afh | work | Acc4
此代碼GroupBy在 上使用id,然后使用 展開組SelectMany,但現在我們Key對每個組都有 。因此,在展開時,重新創建每一行,但將 替換為id的轉換值Key。
uj5u.com熱心網友回復:
分組后AccountInfo,您可以利用為源元素提供索引器的.SelectMany()多載(即AccountInfo值的索引器)。
在以下示例中,我假設您有兩個單獨的類用于原始(可識別)帳戶和偽裝帳戶,例如:
public class BasicAccount
{
public string Name { get; set; }
public string AccountType { get; set; }
}
public class Account : BasicAccount
{
public int AccountInfo { get; set; }
}
public class DisguisedAccount : BasicAccount
{
public string DisguisedInfo { get; set; }
}
如果您的原始帳戶是這樣收集在變數List<Account> accounts中的:
List<Account> accounts = new()
{
new() { Name = "abc", AccountType = "IT", AccountInfo = 3000 },
new() { Name = "bdc", AccountType = "Desk", AccountInfo = 2000 },
new() { Name = "sed", AccountType = "Kitchen", AccountInfo = 3000 },
new() { Name = "afh", AccountType = "work", AccountInfo = 4000 },
new() { Name = "hsfs",AccountType = "home", AccountInfo = 2000 }
};
,你的偽裝賬戶可以產生如下:
IEnumerable<DisguisedAccount> disguisedAccounts = accounts
.GroupBy(a => a.AccountInfo)
.SelectMany(( accountsByInfo, counter ) => accountsByInfo
.Select(account => new DisguisedAccount
{
Name = account.Name,
AccountType = account.AccountType,
DisguisedInfo = $"Acc{counter}"
}));
注意:使用這種方法,您會丟失原始帳戶集合給出的排序。結果集合是:
| 姓名 | 帳戶型別 | 偽裝資訊 |
|---|---|---|
| 美國廣播公司 | 它 | ACC1 |
| sed | 廚房 | ACC1 |
| 直流電 | 桌子 | ACC2 |
| HSFS | 家 | ACC2 |
| afh | 作業 | ACC3 |
示例小提琴在這里。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/446536.html
