Aheho
그는 물었다 11년 전
178

사전 편집하든 포리치 있는 값을 루프

나는 구축하십시오 충스러웠으니 사전이란다 파이라고요 차트입니다 없을 것이다. Before I, I want to 정리하는 표시하십시오 파이라고요 차트입니다 데이터. # 39 m, 제거하기 파이라고요 슬라이스에 i& 될 5% 를 넘지 파이라고요 및 구축하기 받을시간은 &quot Other"; 파이라고요 가공합니다. 하지만, 'm getting a # 39 I& 취합은 수정되었습니다. 열거도 작업이 실행되지 않을 수 있습니다 'idfsysobject. dell. 런타임용으로 개발하십시오.

항목을 추가하거나 제거할 수 없는 이유를 이해할 수 있는 동안 그들에 대한 사전 반복. 하지만, 내가 왜 이해하지 can& don& # 39 의 값을 변경하면 됩니다 t # 39, 기존 키 내부에서 포리치 루프지

제안 사항을 re: 내 코드를 해결 될 것으로 평가했다.

Dictionary<string, int> colStates = new Dictionary<string,int>();
// ...
// Some code to populate colStates dictionary
// ...

int OtherCount = 0;

foreach(string key in colStates.Keys)
{

    double  Percent = colStates[key] / TotalCount;

    if (Percent < 0.05)
    {
        OtherCount += colStates[key];
        colStates[key] = 0;
    }
}

colStates.Add("Other", OtherCount);

답변 12 개

값을 설정할 수 있는 자체 사전 업데이트 버전 number&quot "; - 어떤 무효화됩니다 반복자가 관련된 모든 반복자가 시동키는 또는 값을 뜻한다.

나는한다 내용을 볼 수 있지만, 동시에 이 점을 약간만이라도 홀수입니다 미드플레인 이터레이션에 there& # 39 의 값을 구할 수 없다 - 경우 변경 및 단순화를 위해 버전 번호 하나만.

이러한 종류의 것은 일반적인 방법으로 맞추기 위해 미리 복사합니다를 인컨텍스트 키 컬렉션 및 복사 (copy), 또는 원본 모음이 모음 유지관리하지 하지만 반복할 반복할 수 있는 # 39, ll, 마친 후 변경 you& 적용하십시오 you& # 39 번 반복.

예를 들면 다음과 같습니다.

  • 복사 키 1 *

List<string> keys = new List<string>(colStates.Keys);
foreach(string key in keys)
{
    double percent = colStates[key] / TotalCount;    
    if (percent < 0.05)
    {
        OtherCount += colStates[key];
        colStates[key] = 0;
    }
}

또는.

  • 수정 * 목록 작성

List<string> keysToNuke = new List<string>();
foreach(string key in colStates.Keys)
{
    double percent = colStates[key] / TotalCount;    
    if (percent < 0.05)
    {
        OtherCount += colStates[key];
        keysToNuke.Add(key);
    }
}
foreach (string key in keysToNuke)
{
    colStates[key] = 0;
}

Jon Skeet
Machtyn
그는 5년 전 댓글을 달았습니다
20

이는 이전, 그러니까말이야 신앙이니라 사용하는 .NET 3.5 (아니면 4.0?) linq 와 그러하매 다음과 같이 사용할 수 있습니다.

포리치 (구체화하십시오 키를 콜국가s.키s.토리스트 () {}.

Jon Skeet
그는 5년 전 댓글을 달았습니다
5

@Machtyn: 그러나 나는 것은 분명 문제가 있는지 구체적으로 .NET 2.0, 그렇지 않으면 LINQ 사용한 것이다.

' ()' 를 '포리치' 루프지 토리스트 security. 이러한 방식으로 우리는 임시 변수를 사용할 수 있는 의존하기 때문에 필요한 않습니다 복제본입니다. Linq .Net 3.5.

using System.Linq;

foreach(string key in colStates.Keys.ToList())
{
  double  Percent = colStates[key] / TotalCount;

    if (Percent < 0.05)
    {
        OtherCount += colStates[key];
        colStates[key] = 0;
    }
}

Vasiliy Zverev
user2864740
그는 3년 전 댓글을 달았습니다
1

게 좋을 것 같다 '포리치 var (페어당 콜스테네스토리스트 () 에서)' 을 사용하지 않도록 액세스하십시오 키 [핵심] '에 값을 갖는 콜스테스 기피하고 있는' 이라 할 수 있습니다.

틀렸다니까 수정 취합은 이 라인:

&gt. 콜스테스 [핵심] = 0;

이렇게 하면 뭔가 삭제하고 다시 넣어 기본적으로 이 시점에서 (최대한 리누머이블 애니웨이 우려되고 있다.

    • 멤버 편집하려는 경우 이 값을 저장할 수 있지만, 그 값은 틀렸다니까 약간만이라도 양호임 편집하려는 자체와 이언 험버이블 doesn& # 39, t like that.

이 솔루션은 I& # 39, ve 없애기 위해 사용되는 포리치 루프 및 그냥 루프지 사용합니다. 간단한 for 루프 won& # 39, t, t # 39 변경되는지 확인할지 알고 있는 won& 영향을 뜻한다.

39 의 here& 어떻게 할 수 있다.

List<string> keys = new List<string>(colStates.Keys);
for(int i = 0; i < keys.Count; i++)
{
    string key = keys[i];
    double  Percent = colStates[key] / TotalCount;
    if (Percent < 0.05)    
    {        
        OtherCount += colStates[key];
        colStates[key] = 0;    
    }
}

CodeFusionMobile
Nick Chan Abdullah
그는 3년 전 댓글을 달았습니다
0

내가 사용하는 루프지 afaq afnor 문제 [인덱스화할] [주요] = &quot abc&quot, 사전, 하지만, xyz&quot &quot 초기값을 돌아옵니다.

idbrii
그는 일 년 전 댓글을 달았습니다
0

39 이 코드의 isn& 수정, t for 루프. # 39 에 복사 it& 목록니다 키. (이 경우 여전히 작동합니까 변환되었습니다 redhat. 포리치 루프지) For 루프는 사용하여 '대신' 해결 '키' 를 사용하여 콜국가스스키스 짓궂군요 것이다.

39 의 포리치 아니하고또 시동키는 수정하십시오 너회가 can&, t 값이 있지만 해당 멤버를 직접 수정할 수 있습니다. E. g. 이 노력해야 합니다.

public class State {
    public int Value;
}

...

Dictionary<string, State> colStates = new Dictionary<string,State>();

int OtherCount = 0;
foreach(string key in colStates.Keys)
{
    double  Percent = colStates[key].Value / TotalCount;

    if (Percent < 0.05)
    {
        OtherCount += colStates[key].Value;
        colStates[key].Value = 0;
    }
}

colStates.Add("Other", new State { Value =  OtherCount } );

39, re feeling 할 수 있는 창의적인 you& 경우 이 같은 일이. 루프 뒤로 사전 변경한.

Dictionary<string, int> collection = new Dictionary<string, int>();
collection.Add("value1", 9);
collection.Add("value2", 7);
collection.Add("value3", 5);
collection.Add("value4", 3);
collection.Add("value5", 1);

for (int i = collection.Keys.Count; i-- > 0; ) {
    if (collection.Values.ElementAt(i) < 5) {
        collection.Remove(collection.Keys.ElementAt(i)); ;
    }

}

애니웨이, 확장하지만 관심을 지정값이 동일해집니다 분명 아니다.

그렇다면, 다음 네 할 일을 한 결과 일부 linq 쿼리합니다 그 그래프의 바인딩하면 상대로 사전?.

var under = colStates.Where(c => (decimal)c.Value / (decimal)totalCount < .05M);
var over = colStates.Where(c => (decimal)c.Value / (decimal)totalCount >= .05M);
var newColStates = over.Union(new Dictionary<string, int>() { { "Other", under.Sum(c => c.Value) } });

foreach (var item in newColStates)
{
    Console.WriteLine("{0}:{1}", item.Key, item.Value);
}

Aheho
그는 11년 전 댓글을 달았습니다
0

39 만 t, Linq isn& 볼수 있습니다 (3.5 인치? # 39 m i& 사용하여, .net 2.0.

Scott Ivey
그는 11년 전 댓글을 달았습니다
0

3.5 버전 2.0 에서 사용할 수 있습니다 - that& 시스템스코레.들러 # 39 에 대한 참조를 가진 것이 아니다; d # 39 스맥랜드의 착수할 경우 you& 알려주세요 및 I& # 39, ll 삭제하시겠습니까 대답.

Aheho
그는 11년 전 댓글을 달았습니다
1

39 의 좋은 제안을 했지만, 아마 이 라우트를 검색하기를 못함 It& 패하였다.

그렇게 되면 다른 사람이 같은 문제가 있는 경우 그 자리에 내가 제안하세요 it 전반에 걸쳐 한단다.

대신 새 사전을 만드는 데 필요한 를 이전 수정 파일배치. 같은 소메트린 (또한 이 KeyValuePair&lt 반복할 >; 키를 사용하지 않고 조회:

int otherCount = 0;
int totalCounts = colStates.Values.Sum();
var newDict = new Dictionary<string,int>();
foreach (var kv in colStates) {
  if (kv.Value/(double)totalCounts < 0.05) {
    otherCount += kv.Value;
  } else {
    newDict.Add(kv.Key, kv.Value);
  }
}
if (otherCount > 0) {
  newDict.Add("Other", otherCount);
}

colStates = newDict;

39, 수집, 수정하십시오 can& 있습니다 t 값을 못하고 있다. 이러한 경우 나중에 이를 저장 및 제거할 수 있습니다. 이렇게 끝날 것이라고 말했다.

        Dictionary<string, int> colStates = new Dictionary<string, int>();
        // ...
        // Some code to populate colStates dictionary
        // ...

        int OtherCount = 0;
        List<string> notRelevantKeys = new List<string>();

        foreach (string key in colStates.Keys)
        {

            double Percent = colStates[key] / colStates.Count;

            if (Percent < 0.05)
            {
                OtherCount += colStates[key];
                notRelevantKeys.Add(key);
            }
        }

        foreach (string key in notRelevantKeys)
        {
            colStates[key] = 0;
        }

        colStates.Add("Other", OtherCount);

user2864740
그는 3년 전 댓글을 달았습니다
0
    • 수정하십시오 취합은 수 있습니다. T , can& 있습니다 # 39 를 사용하는 렉시한테서 반복자가 수정되었음 뜻한다.

만일 다른 대답을 함께 생각해봤죠 I& # 39; d '또는' '다음' 스페인디스티오나리스키스 확보하십시오 스페인디스티오나리스발 주 포리치 ', 또한 그 위로 을 (를)' 의 ~ 정렬할지 검색하기를 루프 (loop) 등의 순이었다. 이 때문에 이 방법을 ',' 또는 'SortedDictionary&lt 스키 스키콜레스티온 TValue&gt 스키 복귀하십시오 System.Collections.Generic.SortedDictionary&lt,,, 원래 사전이므로 TValue&gt 이바루크올렉션' 오브젝트에도 유지하는 정렬

4.5 부터는 .NET 사용하면 됩니다 [ConcurrentDictionary&lt 스키 TValue&gt,,] [1]:

using System.Collections.Concurrent;

var colStates = new ConcurrentDictionary<string,int>();
colStates["foo"] = 1;
colStates["bar"] = 2;
colStates["baz"] = 3;

int OtherCount = 0;
int TotalCount = 100;

foreach(string key in colStates.Keys)
{
    double Percent = (double)colStates[key] / TotalCount;

    if (Percent < 0.05)
    {
        OtherCount += colStates[key];
        colStates[key] = 0;
    }
}

colStates.TryAdd("Other", OtherCount);

하지만 실제로는 훨씬 더 단순한 '포리치 사전이므로 성능을 제공할 수 있는 크세스토라리 () '.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

public class ConcurrentVsRegularDictionary
{
    private readonly Random _rand;
    private const int Count = 1_000;

    public ConcurrentVsRegularDictionary()
    {
        _rand = new Random();
    }

    [Benchmark]
    public void ConcurrentDictionary()
    {
        var dict = new ConcurrentDictionary<int, int>();
        Populate(dict);

        foreach (var key in dict.Keys)
        {
            dict[key] = _rand.Next();
        }
    }

    [Benchmark]
    public void Dictionary()
    {
        var dict = new Dictionary<int, int>();
        Populate(dict);

        foreach (var key in dict.Keys.ToArray())
        {
            dict[key] = _rand.Next();
        }
    }

    private void Populate(IDictionary<int, int> dictionary)
    {
        for (int i = 0; i < Count; i++)
        {
            dictionary[i] = 0;
        }
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        BenchmarkRunner.Run<ConcurrentVsRegularDictionary>();
    }
}

결과:.

              Method |      Mean |     Error |    StdDev |
--------------------- |----------:|----------:|----------:|
 ConcurrentDictionary | 182.24 us | 3.1507 us | 2.7930 us |
           Dictionary |  47.01 us | 0.4824 us | 0.4512 us |

[1]: 보기 = netframework-4.7 https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2?

',' 할 수 있습니다 다음 바뀌엇어요 복제본이므로 딕트.발 주 사용할 수 있습니다 '대한' 리스트롬포리치 이터레이션인지 람다 함수 (또는 '포리치' 전에 제안됩니다 루프 등).

new List<string>(myDict.Values).ForEach(str =>
{
  //Use str in any other way you need here.
  Console.WriteLine(str);
});

user2864740
그는 3년 전 댓글을 달았습니다
0

'코드' 를 고려해보십시오 포리치 부작용이 있다.

부인: 내가 C # # 39 don& 많은 것을 하지 않는다.

해스터블 객체를 수정할 수 있는 시도 중인 딕시너옌트리 저장됩니다. 이 전용 매장을 해스터블 객체를 하나 - 귀하의 인스턴스에서는 딕시너옌트리. 주요 변경 또는 값 정도면 되고 열거자가 해스터블 변경하십시오 잘못된 것이다.

할 수 있어 외부에서 루프:

if(hashtable.Contains(key))
{
    hashtable[key] = value;
}

먼저 모든 값의 목록을 만들 시동키는 프로파일링하려는 변경 및 그 목록에 반복할 것이 아니라.