배열 오류 범위 외부의 인덱스를 피하기 위해 배열을 패딩하는 방법
-
13-12-2019 - |
문제
I을 쿼리 할 때 최소한 183 개 이상의 항목을 가질 것으로 예상하지만 때로는 추출물로 인한 결과가 183보다 낮은 항목 수를 나타냅니다. 현재 수정 사항은 카운트가 미만인 경우의 전류 수정 사항을 확대합니다.183.
if (extractArray.Count() < 183) {
int arraysize= extractArray.Count();
var tempArr = new String[183 - arraysize];
List<string> itemsList = extractArray.ToList<string>();
itemsList.AddRange(tempArr);
var values = itemsList.ToArray();
//-- Process the new array that is now at least 183 in length
}
.
하지만 내 해결책이 최선이 아닌 것 같습니다.추출물이 발생할 때마다 최소한 183 개의 항목을 얻을 수 있도록 도와 줄 수있는 다른 솔루션에 감사드립니다.
해결책
배열 기본 클래스는 크기 조정 메소드
if(extractArray.Length < 183)
Array.Resize<string>(ref extractArray, 183);
.
그러나 크기 조정은 성능에 문제가 있으므로이 방법은 어떤 이유로 어레이가 필요한 경우에만 유용합니다.목록으로 전환 할 수있는 경우
여기에서는 실체가없는 문자열 배열이 있으므로 길이 속성을 사용하여 배열의 항목 수를 확인합니다.
다른 팁
다른 사람들의 제안을 따르고 목록을 사용합니다.추가 성능을 위해 "용량"생성자를 사용하십시오.
var list = new List<string>(183);
.
다음에 새 배열을 얻을 때마다 배열을 패드하는 데 사용하는 값을 사용하여 ""바꾸기 "를 수행하십시오.
list.Clear();
list.AddRange(array);
// logically, you can do this without the if, but it saves an object allocation when the array is full
if (array.Length < 183)
list.AddRange(Enumerable.Repeat(" ", 183 - array.Length));
.
이렇게하면 목록은 항상 동일한 내부 배열을 재사용하고 할당 및 GC 압력을 줄이는 것입니다.
또는 확장 방법을 사용할 수 있습니다.
public static class ArrayExtensions
{
public static T ElementOrDefault<T>(this T[] array, int index)
{
return ElementOrDefault(array, index, default(T));
}
public static T ElementOrDefault<T>(this T[] array, int index, T defaultValue)
{
return index < array.Length ? array[index] : defaultValue;
}
}
.
다음 코드가 다음과 같습니다.
items.Zero = array[0];
items.One = array[1];
//...
.
가됩니다.
items.Zero = array.ElementOrDefault(0);
items.One = array.ElementOrDefault(1);
//...
.
마지막으로, 이것은이 답변을 작성하기 시작한 다소 번거로운 아이디어입니다. 183 인덱스가 보장되는 ILIST 구현에서 배열을 래핑 할 수 있습니다 (Brevity의 인터페이스 멤버 구현의 대부분을 생략했습니다.)/ P>
class ConstantSizeReadOnlyArrayWrapper<T> : IList<T>
{
private readonly T[] _array;
private readonly int _constantSize;
private readonly T _padValue;
public ConstantSizeReadOnlyArrayWrapper(T[] array, int constantSize, T padValue)
{
//parameter validation omitted for brevity
_array = array;
_constantSize = constantSize;
_padValue = padValue;
}
private int MissingItemCount
{
get { return _constantSize - _array.Length; }
}
public IEnumerator<T> GetEnumerator()
{
//maybe you don't need to implement this, or maybe just returning _array.GetEnumerator() would suffice.
return _array.Concat(Enumerable.Repeat(_padValue, MissingItemCount)).GetEnumerator();
}
public int Count
{
get { return _constantSize; }
}
public bool IsReadOnly
{
get { return true; }
}
public int IndexOf(T item)
{
var arrayIndex = Array.IndexOf(_array, item);
if (arrayIndex < 0 && item.Equals(_padValue))
return _array.Length;
return arrayIndex;
}
public T this[int index]
{
get
{
if (index < 0 || index >= _constantSize)
throw new IndexOutOfRangeException();
return index < _array.Length ? _array[index] : _padValue;
}
set { throw new NotSupportedException(); }
}
}
.
ack.
183 개의 인덱스가 있는지 확인해야하며, 그렇지 않으면 패드 해야하는 경우 배열 대신 목록을 사용하는 것이 좋습니다.당신은 다음과 같이 할 수 있습니다 :
while (extractList.Count < 183)
{
extractList.Add(" "); // just add a space
}
.
절대로 배열로 돌아 가면 비슷한 것을 사용할 수 있습니다.
이 해결책을 추천 할 것이라고 말할 수는 없지만, 나는 그것을 게시하지 못하게하지 않을 것입니다!그들이 그것을 인정하고 싶은지 여부는 모두가 LINQ 솔루션을 좋아합니다!
LINQ를 사용하여 X 요소가있는 배열이 주어지면 다음과 같이 정확히 Y (183의 경우) 요소가있는 배열을 생성 할 수 있습니다.
var items183exactly = extractArray.Length == 183 ? extractArray :
extractArray.Take(183)
.Concat(Enumerable.Repeat(string.Empty, Math.Max(0, 183 - extractArray.Length)))
.ToArray();
.
183 개 미만의 요소가 있으면 배열이 빈 문자열로 패딩됩니다.183 개 이상의 요소가 있으면 배열이 잘립니다.정확히 183 개의 요소가있는 경우 배열은 그대로 사용됩니다.
나는 이것이 효율적이거나 반드시 좋은 생각임을 주장하지 않는다.그러나 LINQ (Yippee!)를 사용하고 재미 있습니다.