for 루프 기반 인덱스에서 첫 번째 요소를 건너 뛰는 명확한 방법


9

0 기반 배열의 첫 번째 요소를 건너 뛰어야하는 for 루프가 있습니다.

다음 중 내 의도를보다 명확하게 보여주는 것은 무엇입니까?

for($i=1 ; $i < count(array) ; $i++){
    array[$i];
}

또는

for($i=0+1 ; $i < count(array) ; $i++){
    array[$i];
}

28
둘 다 $i=2-1최상의 방법은 아닙니다. : /
yannis

7
아마도 첫 번째 옵션으로 가서 첫 번째 요소를 건너 뛴 이유를 설명하는 주석을 추가 할 것입니다.
Vincent Savard

3
명확성은 내가 목표로하는 것입니다. 질문을 편집했습니다. 더 명확합니까?
Tomas Zubiri

10
PHP를 사용하지 않는 것이 가장 좋은 방법입니다.
cat

3
PHP에는 foreach 구문이 있습니까? 당신은 할 수 있습니다 foreach ($i in range(1, count))(PHP에서 보이는 것). 또는 foreach ($item in array.skip(1))C # 사람이하는 것과 같은 것이 있습니다.
usr

답변:


23

나는 둘 다 싫어.

매직 넘버를 사용할 수 있다고 누가 말했습니까? 1의 오프셋에서 시작하려는 경우 왜 1의 오프셋에서 시작하는지 알려주는 방법은 무엇입니까? 똑같이 마법의 0을 추가하면 나에게 아무것도 설명하지 않습니다.

이것이 페이로드 오프셋입니까? 이것은 null 종료 c 문자열로 변환하는 파스칼 문자열입니까? 무슨 일인지 알려주세요.

미안하지만, 나는 이것과 같은 무의미한 신비를 해독하는 내 경력의 많은 부분을 낭비했으며 그들에 대한 나의 인내심이 얇아졌습니다. 가 괜찮은 이름의 변수는 물어 훨씬 정말?

괜찮은 이름은 첫 번째 요소를 건너 뛰는 이유를 설명하는 이름을 의미합니다. 우리가 첫 번째 요소를 건너 뛰고 있다고 말하는 것은 아닙니다. 1은 그 자체로 나에게 말했다.


20
0과 1은 마법의 숫자가 아닙니다.
user949300

19
@ user949300 아, 확실히 여기 있습니다. 그들은 때로는 마법이 아닌 숫자입니다. 2가 항상 마법의 숫자라고해서 1이 마법의 숫자가되는 것은 아닙니다. 마술은 의미를 잃어 버렸다. 도대체 1 오프셋에서 시작하는 것은 여기서 무엇을 의미합니까? 0을 추가하면 어떤 이점이 있습니까? 예,이 숫자는 확실히 마법입니다. 픽시 더스트가 떨어지는 것을 볼 수 있습니다.
candied_orange

4
물론 static final int LONELIEST_NUMBER = 1모든 Java 코드에서 정의 를 시작하겠습니다 . :-) 즉, 추가 생각에 당신의 답변을 취소하고 싶지만 당신이 그것을 편집하지 않으면 할 수 없습니다. 바보 같은 규칙?
user949300

6
@Eiko : 루프가 두 번째 요소에서 시작되는 이유에 대한 설명이없는 경우, 일부 유지 보수 프로그래머가 첫 번째 요소에서 시작하도록 루프를 변경하는 것이 사실상 보장됩니다. 그렇기 때문에이 문맥에서 숫자 1은 마법의 숫자입니다.
Bart van Ingen Schenau

2
@BartvanIngenSchenau 나는 문맥 내에서 즉시 눈에 보이는 이유가 있다고 가정했습니다. 이전 요소와 요소를 비교하는 것과 같습니다 (1에서 시작하는 가장 빈번한 유스 케이스라고 생각했지만 여기에는 유용한 상수 이름이 표시되지 않습니다). 첫 번째 요소에 매우 특별한 의미가있는 경우 디자인이 손상 될 수 있으며 해당 인덱스의 이름을 지정하는 것보다 더 나은 수정이 있어야합니다. 나는 여기에 변수를 도입 할 이유가 없다고 말하지 않습니다. 그것은 단지 그 경우가 매우 드물다고 생각합니다.
Eiko

12

짧은 대답 : 첫 번째 옵션이 더 좋습니다.

두 번째 옵션은 노이즈를 추가합니다. 0 + 1은 독자가 0이 될 수 있지만 1이라는 것을 이해하는 데 도움이 될 가능성은 거의 없습니다. 특히 모든 배열이 0에서 시작하는 언어에서.

언급했듯이 루프가 0이 아닌 1에서 시작한다는 사실을 강조하려면 주석을 추가하십시오.


10

첫 번째 항목을 건너 뛰고 있다고 말하지 마십시오. 우리는 그것을 볼 수 있습니다. 분명하지 않은 이유는 입니다. 문맥에서 명확하지 않은 경우 이유를 알려주십시오.

// array[0] is just a header
for($i=1 ; $i < count(array) ; $i++){
    array[$i];
}

또는, 당신이 코멘트를 싫어한다면, 다음과 같은 것입니다 :

$lastHeaderIndex = 0;
for($i = $lastHeaderIndex + 1 ; $i < count(array) ; $i++){
    array[$i];
}

언어의 작동 방식 을 생각 나게하기 위해 주석과 속임수를 사용하지 마십시오 .


6

당신의 예는 생각이 든 것 같습니다. 실제 코드에서 루프가 두 번째 배열 요소에서 시작해야한다는 사실은 다음 코드 줄에서 가장 분명합니다. 예를 들어 실제 코드가 다음과 같은 경우

for($i=1 ; $i < count(array) ; $i++){
    array[$i-1]=array[$i];
}

루프가 0 대신 1에서 시작하는 이유를 분명히하기 위해 설명이나 "0 + 1"구문이 필요하지 않습니다.

그러나 루프 내부의 코드가 그 이유를 명백한 방식으로 설명하지 않는 array[0]경우 (특별한 의미가있을 수 있으며 나머지 요소와 다르게 처리해야 함) 설명 설명을 추가하십시오. 그러나 이렇게하기 전에이 array[0]특별한 의미를 피하고 주변 코드를 재구성하면 더 나은 대안이 될 수 있는지 두 번 생각 하십시오.


예제 코드와 같은 상황에서는 변수 이름을 "oneBasedIndex"또는 "zeroBasedIndex"로 지정하고 싶습니다. 그 일에 대해 더 구체적인 것이 더 좋을지라도.
user949300

5

옵션 # 2를 본 적이 없지만 마음에 듭니다. 왜? 옵션 # 1을 사용하면 프로그래머가 배열이 0에서 시작한다는 것을 잊었는지 궁금합니다. 옵션 # 2는 의도적으로 1에서 시작한다는 것을 분명히합니다.

즉, 요소를 건너 뛰는 이유를 설명에 추가하는 것이 가장 좋습니다.

또는 왜 처음부터 시작하는지 쉽게 설명 할 수 있으면 상수를 사용하십시오. 예를 들어, 명령 행 인수를 보면

define ('FIRST_REAL_ARGUMENT', 1);
for ($i=FIRST_REAL_ARGUMENT; ...)

개인적으로 YMMV 대신 주석을 사용하고 싶을 것입니다.


초보자를 다루는 환경 외부에서는 배열이 0에서 시작한다는 것을 잊어 버린 동료의 문제가 없었습니다. 귀하의 작업이 MATLAB과 같은 언어를 사용하는 경우에도 발생할 수 있지만 대부분의 환경에서 프로그래머가 자신의 작업을 알고 있다고 가정합니다. 그리고 1에서 루프를 시작하는 것은 꽤 일반적입니다. 무언가의 첫 번째 요소를 건너 뛰어야하는 몇 가지 이유가 있습니다.
Kat

@Kat 그 이유는 미래의 독자들에게는 분명해야합니다. 차라리 미래의 프로그래머는 그것이 무엇을하고 있는지 모른다고 가정합니다.
A1rPun

2

나는 첫 번째 사람에 의해 혼란 스러울 것입니다. 우리는 모두해야했습니다. 그래서 두 번째 것은 혼동 될 가능성이 훨씬 높습니다. "왜 거기에 0+가 있습니까? 어떻게 든 + 연산자를 무시 했습니까?"

괜찮은 컴파일러는 어쨌든 두 번째 컴파일러를 첫 번째 컴파일러로 전환하지만 PHP를 사용하는 것처럼 보입니다. 따라서 인터프리터가 해당 루프에 도달 할 때마다 실제로 0과 1을 추가해야합니다. 큰 문제는 아니지만 인터프리터가 작동하게 만드는 이유는 무엇입니까?


2

시작점을 설명하는 변수를 사용하십시오.

" 0부터 시작하는 배열의 첫 번째 요소를 건너 뛰어야합니다 "(예 :

skipFirstElement = 1;

for($i=$skipFirstElement ; $i < count(array) ; $i++){
    array[$i];
}

6
나는 변수를 사용하는 것을 좋아하지만이 이름이 싫어. 왜 첫 번째 요소를 건너 뛰는 지 설명하지 않습니다. 1은 어쨌든 말해줍니다. 값이 변경 될 때 이름을 변경해야하는 변수는 무엇입니까? 나는 OP가 왜 우리가 그 이유를 구성해야 할 좋은 이름을 고르는지를 실마리를주지 않았다는 것을 알고 있습니다. 더 나은 이름이 없다면 나는 오히려 1을 다시 가질 것입니다.
candied_orange

@CandiedOrange 변수 이름이 더 의미가 있어야한다는 데 동의하지만 제시 된 문제는 왜 첫 번째 값을 건너 뛰려고하는지 설명하지 않습니다. 내 요점은, 예를 들어 저자가 그에게 가장 적합한 이름을 선택할 수 있다는 것입니다.
catta

이런 식으로 가르치지 마십시오. 이것은 충분히 혼란 스럽다. 많은 코더들에게는 가장 쉬운 이름을 사용하여 이해하기 어려운 코드 작성으로 되돌아 갈 수 있습니다. 진지하게, 나는 이것보다 1을 다루고 싶습니다.
candied_orange

1
//We are skipping the first element because...    
if ($i==0)  
{    continue;      } 

모든 루프가 0에서 시작하여 강박적인 경우 continue 문을 사용할 수 있습니다. 평소와 달리 건너 뛰지 않는 이유에 대한 설명을 추가하십시오.


2
이 옵션의 문제점은 모든 단일 요소에 대해 이것을 평가하고 루프에 n 개의 비교를 추가하는 동시에 다른 방법을 통해 첫 번째 요소를 건너 뛰는 것 (i = 1로 시작하는 배열 이동) )은 필요한 작업 만 수행하는 것을 의미합니다.
Kevin Fee

3
@KevinFee 대규모 배열을 다루지 않는다면이 간단한 비교는 문제가되지 않을 것입니다. 그리고 나는 if first then skip왜 그런지에 대한 언급과 함께 명시 성을 좋아합니다 . 아직 상황이 없다면 "최고의"솔루션은 없습니다
Ivan Pintar

-2

내가 할 일은 루핑하기 전에 첫 번째 요소를 제거하는 것입니다. 필요한 경우 새 배열을 만듭니다. 왜 당신이 그것을하고 있는지 의견을 설명하십시오. 그런 다음 간단한 foreach를 수행하십시오.

$arrayCopy = $array; // in case you don't want to touch the original array
array_shift($arrayCopy); // removing first element because of X reason.
foreach($arrayCopy => $element) { 
    // do stuff
}

이렇게하면 의도가 분명합니다.

더 명확히하기 위해 코드를 적절한 이름으로 메소드에 래핑하여 더 명확하게 만들 수 있습니다.

function doStuffToAllButTheFirst($array) { // this copies the original array, so there are no sideffects
    array_shift($array);
    foreach($array => $element) { // do stuff }  
}

그러나이 모든 것에는 여전히 맥락이 없습니다. 요소로 무엇을하고 싶습니까? 새 어레이를 반환 하시겠습니까? 당신은 당신이 후에 원본과 새로운 배열에 관심이 doStuff()있습니까?

어쨌든 여기에 명확한 대답이 없으며 코드를 읽을 수 있도록 만드는 방법은 컨텍스트에 따라 다릅니다.


1
나는 인덱스를 처리 할 필요가 없기 때문에 이것을 좋아합니다. 항상 플러스입니다.
Tomas Zubiri

1
단점은 부작용을 원하지 않으면 전체 어레이를 복사해야한다는 것입니다.
Tomas Zubiri

1
우리가 1에서 시작하는 이유가 $array[$i-1] = $array[$i]@DocBrown의 답변에 따라 우리가하고 있거나 비슷한 것이기 때문에 어떨까요?
Kevin Fee

1
이것은 나에게 끔찍한 것 같습니다. 모든 비 효율성, 부작용 및 매우 일반적인 사용 사례를 해결할 수없는 능력 1(케빈 리의 의견 참조) 외에도 코드를 더 명확하게 만들지는 않습니다. 독자는 array_shift, 기능, 작동 방식을 이해해야합니다. 이 코드 줄이 버그일까요? 배열을 수정하거나 새 배열을 반환합니까? 요소를 삽입하거나 제거합니까? 지수가 바뀌나요? 1 기반 루프를 사용하는 것이 그 기능에서 크게 개선 되지 않는 방법을 보지 못했습니다 (이름이 주어지면 즉시 이해할 수 있음).
Eiko

1
이러한 질문에 대한 답변은 상황에 따라 크게 다릅니다. 그리고 효율성에 관해서는, 나는 하루 동안 foreach를 인수했습니다 ... 대부분의 경우 성능 차이가 거의 보이지 않습니다.
Ivan Pintar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.