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.