- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个包含字符串和字典的字符串数组。
String [] str_array;
Dictionary<int, string> dict = new Dictionary<int, string>();
dict = str_array.toDictionary();
如何将数组放入具有 int 和 String 的字典中?我已经看过所有这些使用 bool 的示例,但我需要 int 和 string。
int(键)将只是字典(dict.count)的实际位置,值将是数组在该位置的值。
编辑:感谢所有答案,但我不想遍历数组。我假设使用 array.toDictionary 的性能会比遍历数组并将数组的值分配给字典更好。数组可能有 5k 个元素。
edit2:原因是我必须将字典传递给方法……这是必需的。我所有的值都在一个简单的数组中。
edit3:最重要的是性能。也许遍历数组并将值分配给 dict 比 array.toDictionary 更快,但问题是我没有那么小的代码来对两者进行基准测试。
最佳答案
首先 - 你的性能问题很有趣并且有点过早优化的味道 - 正如这个答案将显示的那样,你可能会看到 for
之间的性能差异几毫秒。循环和 ToDictionary
.
除非您在实时系统中运行它,否则我看不出有什么问题。
关于节目 - 以下是我能想到的三种(半)不同的构建字典的粗略基准(只有真实世界的时间是可靠的)。第一个使用 for
循环,第二个做同样的事情但不使用数组的 Length
属性(property)(仅用于利息);第三次和第四次使用ToDictionary
;一个使用 Select
一个使用计数器变量(混合):
[TestMethod]
public void SomeBenchmark()
{
List<double> forLoopTimes = new List<double>();
List<double> forLoop2Times = new List<double>();
List<double> toDictionaryTimes = new List<double>();
List<double> hybridTimes = new List<double>();
string[] array = Enumerable.Range(0, 5000).Select(i => i.ToString()).ToArray();
Dictionary<int, string> dictionary;
int runCount = 5000;
int arrayLen = array.Length;
while (runCount-- != 0)
{
Stopwatch sw = Stopwatch.StartNew();
dictionary = new Dictionary<int, string>();
for (int i = 0; i < array.Length; i++)
{
dictionary[i] = array[i];
}
sw.Stop();
forLoopTimes.Add(sw.Elapsed.TotalMilliseconds);
sw.Restart();
dictionary = new Dictionary<int, string>();
for (int i = 0; i < arrayLen; i++)
{ //same as before - but using arrayLen instead of property
dictionary[i] = array[i];
}
sw.Stop();
forLoop2Times.Add(sw.Elapsed.TotalMilliseconds);
sw.Restart();
dictionary = array.Select((s, i) => new { Key = i, Value = s }).ToDictionary(v => v.Key, v => v.Value);
sw.Stop();
toDictionaryTimes.Add(sw.Elapsed.TotalMilliseconds);
int counter = 0;
sw.Restart();
dictionary = array.ToDictionary(s => counter++, s => s);
sw.Stop();
hybridTimes.Add(sw.Elapsed.TotalMilliseconds);
}
Console.WriteLine("for loop average: {0} milliseconds", forLoopTimes.Average());
Console.WriteLine("for loop(2) average: {0} milliseconds", forLoop2Times.Average());
Console.WriteLine("ToDictionary average: {0} milliseconds", toDictionaryTimes.Average());
Console.WriteLine("Hybrid average: {0} milliseconds", hybridTimes.Average());
}
结果(发布版本,在我的戴尔 2.4Ghz 工作站上运行大约需要 20 秒):
For loop average: 0.28880804 milliseconds
For loop(2) average: 0.2773845 milliseconds
ToDictionary average: 0.479094339999998 milliseconds
Hybrid average: 0.353655779999999 milliseconds
所以 for
loop 无疑更快 - 至少比最近的 ToDictionary
快 22%执行。我用 100,000 个元素进行了尝试,然后它达到了大约 30%。
注意第二个for
循环结果 - 似乎暗示绕过 Length
属性(property)是个好主意。事实上,我已经连续运行了 4 次,结果如下(包括上面的第一个):
For loop: 0.28880804, 0.28562478, 0.283770739999999, 0.287241679999999
For loop(2): 0.2773845, 0.27621306, 0.27869996, 0.27962916
ToDictionary: 0.479094339999998, 0.476417939999997, 0.476162219999997, 0.475776479999997
Hybrid: 0.353655779999999, 0.3583224, 0.352022739999998, 0.349865779999999
但是,我也看到至少一个基准测试的结果翻转了 - 证明了这种基准测试在很大程度上是毫无意义的。实际上,我们也应该为每个测试生成一个不同的数组,以避免缓存等。
还有一个选择。
如果您调用的方法接受 IDictionary<int, string>
(注意——界面);而不是 Dictionary<int, string>
您可以创建一个简单的包装器类型来实现接口(interface)的必要成员,从而完全避免投影到字典中的需要;只要只需要某些成员。这是一个几乎完整的实现:
public class FakeDictionary : IDictionary<int, string>
{
private readonly string[] _array;
public FakeDictionary(string[] array)
{
_array = array;
}
#region IDictionary<int,string> Members
public void Add(int key, string value)
{
throw new NotSupportedException();
}
public bool ContainsKey(int key)
{
return key >= 0 && key < _array.Length;
}
public ICollection<int> Keys
{
get { return Enumerable.Range(0, _array.Length).ToArray(); }
}
public bool Remove(int key)
{
throw new NotSupportedException();
}
public bool TryGetValue(int key, out string value)
{
value = null;
if (key >= 0 && key < _array.Length)
{
value = _array[key];
return true;
}
return false;
}
public ICollection<string> Values
{
get { return _array; }
}
public string this[int key]
{
get
{
try
{
return _array[key];
}
catch (ArgumentOutOfRangeException ex)
{
throw new KeyNotFoundException("Invalid key", ex);
}
}
set //note - can't be used to add items
{
try
{
_array[key] = value;
}
catch (ArgumentOutOfRangeException ex)
{
throw new KeyNotFoundException("Invalid key", ex);
}
}
}
#endregion
#region ICollection<KeyValuePair<int,string>> Members
public void Add(KeyValuePair<int, string> item)
{
throw new NotSupportedException();
}
public void Clear()
{
throw new NotSupportedException();
}
public bool Contains(KeyValuePair<int, string> item)
{
return ContainsKey(item.Key) && _array[item.Key].Equals(item.Value);
}
public void CopyTo(KeyValuePair<int, string>[] array, int arrayIndex)
{
//too much for an SO answer.
throw new NotImplementedException();
}
public int Count
{
get { return _array.Length; }
}
public bool IsReadOnly
{
//technically it's not - because we can modify individual elements -
//but at the collection-level it is
get { return true; }
}
public bool Remove(KeyValuePair<int, string> item)
{
throw new NotSupportedException();
}
#endregion
#region IEnumerable<KeyValuePair<int,string>> Members
public IEnumerator<KeyValuePair<int, string>> GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
}
关于c# - 使用int和string将数组转换为字典c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11523175/
我正在尝试使用 y 组合器在 Scala 中定义 gcd: object Main { def y[A,B]( f : (A => B) => A => B ) : A => B = f(y(f)
我正在尝试了解返回指向函数的指针的函数,在我尝试编译代码后,它给了我这种错误: cannot convert int (*(int))(int) to int (*(int))(int) in ass
所以我一直在关注 youtube 上的游戏编程教程,然后弹出了这段代码:bufferedImageObject.getRGB(int, int, int, int, int[], int, int);
我正在将时间现在 与存储在数据库某处的时间进行比较。数据库中存储的时间格式为“yyyyMMddHHmmss”。例如,数据库可能会为存储的时间值返回 201106203354。然后我使用一个函数将时间现
例如 Maze0.bmp (0,0) (319,239) 65 120 Maze0.bmp (0,0) (319,239) 65 120 (254,243,90) Maze0.bmp (0,0) (
评论 Steve Yegge的post关于 server-side Javascript开始讨论语言中类型系统的优点和这个 comment描述: ... examples from H-M style
我正在研究 C 的指针,从 Deitel 的书中我不明白 int(*function)(int,int) 和 int*function(int, int) 表示函数时。 最佳答案 C 中读取类型的经验
您好,我使用 weblogic 11g 创建 war 应用程序,我对 joda time 的方法有疑问 new DateTime(int, int, int, int, int, int); 这抛出了
Create a method called average that calculates the average of the numbers passed as parameters. The
var a11: Int = 0 var a12: Int = 0 var a21: Int = 0 var a22: Int = 0 var valueDeterminant = a11 * a12
我正在为一个项目设置 LED 阵列。我得到了一个 LED 阵列,可以根据引脚变化电压进行更改,但我无法添加更多引脚。 当我尝试时,编译失败并显示错误:函数“int getMode(int, int,
除了创建对列表执行简单操作的函数之外,我对 haskell 还是很陌生。我想创建一个列表,其中包含 Int 类型的内容, 和 Int -> Int -> Int 类型的函数. 这是我尝试过的: dat
这个问题已经有答案了: Java add buttons dynamically as an array [duplicate] (4 个回答) 已关闭 7 年前。 StackOverFlow问题今天
我有几个 EditText View ,我想在其中设置左侧的图像,而 setCompoundDrawablesWithIntrinsicBounds 似乎不起作用。图形似乎没有改变。 有人知道为什么会
#include using namespace std; int main() { static_assert(is_constructible, int(*)(int,int)>::val
fun sum(a: Int, b: Int) = a + b val x = 1.to(2) 我在找: sum.tupled(x),或者 sum(*x) 当然,以上都不能用 Kotlin 1.1.3
有一个函数: func (first: Int) -> Int -> Bool -> String { return ? } 返回值怎么写?我对上面 func 的返回类型感到很困惑。 最
type foo = A of int * int | B of (int * int) int * int 和 (int * int) 有什么区别?我看到的唯一区别在于模式匹配: let test_
我正在尝试制作一个 slider 游戏。在这个类中,我使用 Graphics 对象 g2 的 drawImage 方法来显示“拼图”的 block 。但在绘制类方法中,我收到此错误:找不到符号方法dr
我试着理解这个表达: static Func isOdd = i => (i & 1) == 1; 但是这是什么意思呢? 例如我有 i = 3。然后 (3 & 1) == 1 或 i = 4。然后
我是一名优秀的程序员,十分优秀!