배열의 모든 값이 같은지 확인하십시오


190

모든 값이 동일한 배열을 찾아야합니다. 가장 빠른 방법은 무엇입니까? 그것을 반복하고 값을 비교해야합니까?

['a', 'a', 'a', 'a'] // true
['a', 'a', 'b', 'a'] // false

1
@TJCrowder 나는 당신이 이미 최고의 솔루션에 대해 생각하고 있다고 확신합니다;)
VisioN

2
@TJCrowder : 실제로 답변을 수락하려는 요청자의 의지는 말할 것도 없습니다. 담당자가 1 명인 사용자는 요즘 복사하여 붙여 넣기 가능한 답을 얻 자마자 떠나는 유형을 묻고 실행하는 것처럼 보입니다.
Cerbrus

1
이 접근법 주위에 뭔가가 작동해야합니까? a.join(',').split(a[0]).length === a.length + 1
Jashwant

1
@ TomášZato : "OP"는 "원래 포스터"(질문을하는 사람)를 의미합니다.
TJ Crowder 2013

답변:


288
const allEqual = arr => arr.every( v => v === arr[0] )
allEqual( [1,1,1,1] )  // true

또는 하나의 라이너 :

[1,1,1,1].every( (val, i, arr) => val === arr[0] )   // true

Array.prototype.every (MDN에서) :이 every()메소드는 배열의 모든 요소가 제공된 함수로 구현 된 테스트를 통과하는지 테스트합니다.


10
간결함은 지혜의 영혼입니다
svarog

1
jsperf 사례를 만들었습니다 . 이 방법은 대부분의 후보보다 성능이 우수합니다.
Junliang Huang

1
const everythings_equal = array => array.every(thing => thing === array[0]);
Константин Ван

8
사용 some대신에 every: arr.some( v => v !== arr[0] ). 이것은 같지 않은 첫 번째 요소에서 일찍 반환됩니다 arr[0].
Jan

2
@Jan every도 일찍 돌아옵니다.
golopot

111

편집 : 빨간 닌자가 되십시오 :

!!array.reduce(function(a, b){ return (a === b) ? a : NaN; });

결과 :

var array = ["a", "a", "a"] => result: "true"
var array = ["a", "b", "a"] => result: "false"
var array = ["false", ""] => result: "false"
var array = ["false", false] => result: "false"
var array = ["false", "false"] => result: "true"
var array = [NaN, NaN] => result: "false" 

경고:

var array = [] => result: TypeError thrown

initialValue를 전달하지 않기 때문 입니다. 따라서 array.length먼저 확인하고 싶을 수도 있습니다 .


5
파티에 약간 늦을 수도 있습니다 ... 배열이 falses 로 구성되어 있으면 작동하지 않는다고 생각합니다 ! 예를 들어 [false, false, false] .reduce (function (a, b) {return (a === b)? a : false;});
George Flourentzos

3
@Martin : ["false", ""]반환 true: /
dalgard

6
이는을 사용하여 한 단계 업그레이드 할 수 있습니다 NaN. 모두 있기 때문에 NaN === NaN그리고 NaN !== NaN거짓, 그것은 한 번 보장 prevNaN이 설정되어 다음 값이 꺼내 수 있습니다. 또한 이중 부정을 추가하면 결과 가 거짓 이므로 true및 로 변환 됩니다. 최종 형태 :falseNaN!!array.reduce(function(a, b){ return (a === b) ? a : NaN; });
Filipe Silva

3
다운로드 됨 . 요소가 동일하지만 허위 인 경우 어떻게해야 합니까?
Константин Ван

3
부울 값으로 작동하지 않기 때문에 하향 투표했습니다.
Tyguy7

62

작동합니다. 프로토 타입을 사용하여 Array에 메소드를 작성합니다.

if (Array.prototype.allValuesSame === undefined) {
  Array.prototype.allValuesSame = function() {
    for (let i = 1; i < this.length; i++) {
      if (this[i] !== this[0]) {
        return false;
      }
    }
    return true;
  }
}

이 방법으로 이것을 호출하십시오 :

let a = ['a', 'a', 'a'];
let b = a.allValuesSame(); // true
a = ['a', 'b', 'a'];
b = a.allValuesSame();     // false

5
아주 훌륭하지만주의하십시오 : IE는 프로토 타입 할당 방법을 지원하지 않습니다. 어쨌든 사용합니다.
Tomáš Zato-복권 모니카

5
@ TomášZato : IE는 Array.prototypeIE6까지 의 기능 향상을 지원합니다 . 일부 이전 버전의 IE에서는 기능 보강을 지원하지 않는 것은 DOM 요소 프로토 타입 일뿐입니다.
TJ Crowder 2013

4
원숭이가 내장 프로토 타입을 패치하는 것은 좋은 생각이 아닙니다. 여러 라이브러리가 그렇게하면 예기치 않은 동작이 발생하여 디버깅하기가 매우 어려울 수 있습니다.
Mark Wilbur

1
@MarkWilbur +1 특히 다음 어레이에서 for..in 루프를 수행하는 경우 allValuesSame루프를 경험하게됩니다
Olivier Pons

1
나는 의도를 바꾸지 않고 이것을 현대화했습니다.
Mr. Polywhirl

30

JavaScript 1.6에서는 다음을 사용할 수 있습니다 Array.every.

function AllTheSame(array) {
    var first = array[0];
    return array.every(function(element) {
        return element === first;
    });
}

예를 들어 배열에 요소가없는 경우 일부 위생 검사가 필요할 수 있습니다. (또한 모든 요소가 NaN이후 에는 작동하지 NaN !== NaN않지만 문제가되지는 않습니다 ... 그렇습니까?)


30

어레이를 세트로 전환 할 수 있습니다. Set의 크기가 1과 같으면 Array의 모든 요소가 동일합니다.

function allEqual(arr) {
  return new Set(arr).size == 1;
}

allEqual(['a', 'a', 'a', 'a']); // true
allEqual(['a', 'a', 'b', 'a']); // false

훌륭한. 그냥 참고 allEqual([NaN, NaN])있습니다 true이 경우.
Константин Ван

12

성능 비교를 위해 벤치마킹도 수행했습니다.

function allAreEqual(array){
    if(!array.length) return true;
    // I also made sure it works with [false, false] array
    return array.reduce(function(a, b){return (a === b)?a:(!b);}) === array[0];
}
function same(a) {
    if (!a.length) return true;
    return !a.filter(function (e) {
        return e !== a[0];
    }).length;
}

function allTheSame(array) {
    var first = array[0];
    return array.every(function(element) {
        return element === first;
    });
}

function useSome(array){
    return !array.some(function(value, index, array){
        return value !== array[0];
    });
}

결과 :

allAreEqual x 47,565 ops/sec ±0.16% (100 runs sampled)
same x 42,529 ops/sec ±1.74% (92 runs sampled)
allTheSame x 66,437 ops/sec ±0.45% (102 runs sampled)
useSome x 70,102 ops/sec ±0.27% (100 runs sampled)

따라서 내장 array.some ()을 사용하는 것이 샘플링 된 것 중 가장 빠른 방법입니다.


3
더 성능이 좋은 것을 확인하는 것이 좋습니다. Array#some콜백 함수가 true를 반환하면 반복이 중지되기 때문에 때때로 성능이 뛰어난 이유 는 다음과 같습니다. 따라서 모든 요소가 실제로 같으면 성능이와 같아야합니다 Array#every. 모든 요소가 같지 않을 때의 상대 성능은 첫 번째 일치하지 않는 요소의 색인에 따라 다릅니다.
danmactough

3
좋은데 lol 함수를 사용하여 각각의 이름을 지정할 수 있습니다. 예 : 감소, 필터링, 매번
Z. Khullah

네이티브 for 루프의 경우 5 배 이상으로이 모든 것을 능가합니다.
PirateApp

9

밑줄 / lodash를 사용한 최단 답변

function elementsEqual(arr) {
    return !_.without(arr, arr[0]).length
}

투기:

elementsEqual(null) // throws error
elementsEqual([]) // true
elementsEqual({}) // true
elementsEqual([1]) // true
elementsEqual([1,2]) // false
elementsEqual(NaN) // true

편집하다:

또는 Tom의 답변에서 영감을 얻은 더 짧습니다.

function elementsEqual2(arr) {
    return _.uniq(arr).length <= 1;
}

투기:

elementsEqual2(null) // true (beware, it's different than above)
elementsEqual2([]) // true
elementsEqual2({}) // true
elementsEqual2([1]) // true
elementsEqual2([1,2]) // false
elementsEqual2(NaN) // true

6

이미 underscore.js를 사용하고 있다면 다음을 사용하는 또 다른 옵션이 있습니다 _.uniq.

function allEqual(arr) {
    return _.uniq(arr).length === 1;
}

_.uniq중복없는 버전의 배열을 반환합니다. 모든 값이 동일하면 길이는 1입니다.

주석에서 언급했듯이 빈 배열이 반환 될 것으로 예상되면 true그 경우도 확인해야합니다.

function allEqual(arr) {
    return arr.length === 0 || _.uniq(arr).length === 1;
}

그러나 배열이 비어 있으면 답이을 반환 false합니다. 나는 그것이 있어야한다고 생각하지만 true. .length <= 1그래도 변경하면 충분합니다.
평균 Joe

@Kasztan 그것은 공정한 포인트입니다. 그 사건을 다루기 위해 답변을 업데이트했습니다.
Tom Fenech

6

예, 아래의 필터를 사용하여 확인할 수도 있습니다. 매우 간단합니다. 모든 값을 확인하면 첫 번째 값과 동일합니다.

//ES6
function sameValues(arr) {
  return arr.filter((v,i,a)=>v===a[0]).length === arr.length;
} 

배열의 모든 메소드를 사용하여 수행 할 수도 있습니다.

//ES6
function sameValues(arr) {
  return arr.every((v,i,a)=>v===a[0]);
} 

아래와 같이 배열을 확인할 수 있습니다.

sameValues(['a', 'a', 'a', 'a']); // true
sameValues(['a', 'a', 'b', 'a']); // false

또는 많이 재사용하는 경우 JavaScript의 기본 배열 기능에 추가 할 수 있습니다.

//ES6
Array.prototype.sameValues = Array.prototype.sameValues || function(){
 this.every((v,i,a)=>v===a[0]);
}

아래와 같이 배열을 확인할 수 있습니다.

['a', 'a', 'a', 'a'].sameValues(); // true
['a', 'a', 'b', 'a'].sameValues(); // false

5

Array.every지원되는 경우 사용할 수 있습니다 .

var equals = array.every(function(value, index, array){
    return value === array[0];
});

루프의 대안 접근 방식은 다음과 같습니다. sort

var temp = array.slice(0).sort();
var equals = temp[0] === temp[temp.length - 1];

또는 항목이 질문과 같은 경우 더러워진 것입니다.

var equals = array.join('').split(array[0]).join('').length === 0;

또한 작동합니다.


첫 번째 예가 거꾸로 있습니다. 이어야 equals = !array.some( (v,i,a) => v!==a[0] )합니다. 그렇지 않으면 어떤 값이든 첫 번째 값과 일치하는지 확인하는 것입니다. 물론 항상 참입니다 :)
Mark Kahn

정확히 말하면, 나는 첫 번째 단락에서 언급 한 some대신에 사용 했습니다 every. :) 캐치 주셔서 감사합니다!
ZER0

5

이 one-liner가 Array.prototype.every , Object.is 및 ES6 화살표 함수를 사용하여 원하는 작업을 수행하도록 할 수 있습니다 .

const all = arr => arr.every(x => Object.is(arr[0], x));

2
제안하는 솔루션을 설명하십시오.
il_raffa

3

가장 간단한 방법은 각 값을 다음 값과 비교하는 루프를 만드는 것입니다. "체인"이 끊기면 거짓을 반환합니다. 첫 번째가 두 번째와 같고 두 번째가 세 번째와 같으면 배열의 모든 요소가 서로 같다고 결론을 내릴 수 있습니다.

배열 데이터 []가 주어지면 다음을 사용할 수 있습니다.

for(x=0;x<data.length - 1;x++){
    if (data[x] != data[x+1]){
        isEqual = false;            
    }
}
alert("All elements are equal is " + isEqual);

3
arr.length && arr.reduce(function(a, b){return (a === b)?a:false;}) === arr[0];

3

새로운 솔루션 업데이트 : 인덱스 확인

 let a = ['a', 'a', 'b', 'a'];
 let a = ['a', 'a', 'a', 'a'];
 let check = (list) => list.every(item => list.indexOf(item) === 0);
 check(a); // false;
 check(b); // true;

ES6로 업데이트 : 사용 list.every이 가장 빠른 방법입니다.

 let a = ['a', 'a', 'b', 'a'];
 let check = (list) => list.every(item => item === list[0]);

구 버전:

      var listTrue = ['a', 'a', 'a', 'a'];
      var listFalse = ['a', 'a', 'a', 'ab'];

      function areWeTheSame(list) { 
         var sample = list[0];
         return (list.every((item) => item === sample));
      }

2

이것을 사용할 수 있습니다 :

function same(a) {
    if (!a.length) return true;
    return !a.filter(function (e) {
        return e !== a[0];
    }).length;
}

이 함수는 먼저 배열이 비어 있는지 확인합니다. 값이 같다면 배열을 필터링하고 첫 번째 요소와 다른 모든 요소를 ​​취합니다. 그러한 값이 없으면 => 배열에는 동일한 요소 만 포함됩니다. 그렇지 않으면 배열이 그렇지 않습니다.



1
var listTrue = ['a', 'a', 'a', 'a'];
var listFalse = ['a', 'a', 'a', 'ab'];

function areWeTheSame(list) { 
    var sample = list[0];
    return !(list.some(function(item) {
        return !(item == sample);
    }));
}

또한 일부 코드를 붙여 넣는 대신 수행 한 작업을 설명하십시오.
Wouter J

1

간단 해. 함수를 작성하고 매개 변수를 전달하십시오. 이 함수에서 첫 번째 색인을 새 변수에 복사하십시오. 그런 다음 for 루프를 만들고 배열을 반복합니다. 루프 내에서 새로 작성된 변수가 루프의 모든 요소와 동일한 지 여부를 확인하는 조건으로 while 루프를 작성하십시오. for 루프가 완료된 후 동일한 리턴 true이면 while 루프 내에서 false를 리턴하십시오.

function isUniform(arra){
    var k=arra[0];
    for (var i = 0; i < arra.length; i++) {
        while(k!==arra[i]){
            return false;
        }
    }
    return true;
}

1

허용 대답은 좋은 일을하지만 난 작은 비트를 추가하고 싶었다. ===객체 배열을 비교했기 때문에 사용 하기 가 쉽지 않았지만 앱 전체에서 필자가 권장하는 매우 깊고 빠른 패키지를 사용하고 있습니다. 이를 통해 내 코드는 다음과 같습니다.

let areAllEqual = arrs.every((val, i, arr) => equal(val, arr[0]) );

내 데이터는 다음과 같습니다.

[  
  [
    {
      "ID": 28,
      "AuthorID": 121,
      "VisitTypeID": 2
    },
    {
      "ID": 115,
      "AuthorID": 121,
      "VisitTypeID": 1
    },
    {
      "ID": 121,
      "AuthorID": 121,
      "VisitTypeID": 1
    }
  ],
  [
    {
      "ID": 121,
      "AuthorID": 121,
      "VisitTypeID": 1
    }
  ],
  [
    {
      "ID": 5,
      "AuthorID": 121,
      "VisitTypeID": 1
    },
    {
      "ID": 121,
      "AuthorID": 121,
      "VisitTypeID": 1
    }
  ]
]

1
  1. 배열을 결합하여 문자열을 만듭니다.
  2. 주어진 배열의 첫 문자를 반복하여 문자열을 만듭니다.
  3. 두 문자열을 일치

	function checkArray(array){
		return array.join("") == array[0].repeat(array.length);	
	}

	console.log('array: [a,a,a,a]: ' + checkArray(['a', 'a', 'a', 'a']));
	console.log('array: [a,a,b,a]: ' + checkArray(['a', 'a', 'b', 'a']));

그리고 당신은 끝났습니다!


1

이제 세트를 사용하여 쉽게 할 수 있습니다.

let a= ['a', 'a', 'a', 'a']; // true
let b =['a', 'a', 'b', 'a'];// false

console.log(new Set(a).size === 1);
console.log(new Set(b).size === 1);


1

for 루프를 사용할 수 있습니다 :

function isEqual(arr) {
  var first = arr[0];
  for (let i = 1; i < arr.length; i++) {
    if (first !== arr[i]) {
      return false;
    }
  }
  return true;
}

0

글쎄, 이것은 실제로 그렇게 복잡하지 않습니다. 당신이 시도조차하지 않았다는 강한 의혹이 있습니다. 당신이하는 일은 첫 번째 값을 선택하여 변수에 저장 한 다음 for루프 내에서 모든 후속 값을 첫 번째 값과 비교하는 것입니다.
의도적으로 코드를 공유하지 않았습니다. for사용 방법과 변수 비교 방법을 찾으십시오 .


8
이 답변이 마음에 들지 않습니다. 두 번째 값이 세 번째 값과 같은지 여부를 알려주지 않습니다. 분명히 중첩 된 루프가 그렇게 할 것입니다.하지만 개념적으로 초보자 스크립터와 다릅니다.
jtromans

3
@jtromans : 평등의 전이 속성으로 인해 A == B이고 A == C이면 B == C를 알 수 있습니다. 중첩 된 루프 등을 사용하여 "수동으로"확인할 필요는 없습니다. 단일 값 (어떤 값이 아닌 배열의 첫 번째 값)에 대한 비교를 반복하는 것이이 대답에서 제안하는 것과 정확히 일치합니다.
ov

@ov 실제로, 나는 서둘러 질문을 잘못 읽었습니다. 그 당시에는 모든 값이 같은지 확인하는 것 이상이 필요하다고 생각했습니다 (! duh).
jtromans

9
복잡하지 않습니다. 그리고 페이지의 다른 답변도 없습니다. 그러나 나 에게이 답변은 가장 도움이되지 않습니다.
Charlie

1
그것은 원래 그가 질문을하기 전에 그가 생각하려고하는 OP 주장을 강력하게 지적하기위한 것이었다.
Tomáš Zato-복직 모니카

0

간단한 한 줄 솔루션으로, 첫 번째 항목으로 채워진 배열과 비교하십시오.

if(arr.join('') === Array(arr.length).fill(arr[0]).join(''))

그것은 어디에서나 사용할 수있는 솔루션처럼 보이지 않습니다
Lu4

괜찮아요. function arrayOfSame (arr) {return (arr.join ( '') == (new Array (arr.length + 1) .join (arr [0]))); }
Arkain

0

ES6 화살표 함수 구문을 사용할 때의 또 다른 흥미로운 방법은 다음과 같습니다.

x = ['a', 'a', 'a', 'a']
!x.filter(e=>e!==x[0])[0]  // true

x = ['a', 'a', 'b', 'a']
!x.filter(e=>e!==x[0])[0] // false

x = []
!x.filter(e=>e!==x[0])[0]  // true

그리고 배열 (x)에 변수를 재사용하지 않으려는 경우 :

!['a', 'a', 'a', 'a'].filter((e,i,a)=>e!==a[0])[0]    // true

array.every (...)를 사용한 IMO 이전 포스터가 가장 깨끗한 솔루션입니다.


0
function isUniform(array) {   
  for (var i=1; i< array.length; i++) {
    if (array[i] !== array[0]) { return false; }
  }

  for (var i=1; i< array.length; i++) {
    if (array[i] === array[0]) { return true; }
  }
}
  • 첫 번째 루프의 경우 고르지 않을 때마다 "false"를 반환합니다
  • 첫 번째 루프가 실행되고 false를 반환하면 "false"
  • false를 반환하지 않으면 true가된다는 의미이므로 두 번째 루프를 수행합니다. 그리고 물론 우리는 두 번째 루프에서 "참"을 가질 것입니다 (첫 번째 루프가 거짓이 아니기 때문에)

0

이것은 작동 할 수 있습니다. 주어진 scenerio와 잘 작동하는 주석 출력 코드를 사용할 수도 있습니다.

function isUniform(){
	var arrayToMatch = [1,1,1,1,1];
	var temp = arrayToMatch[0];
	console.log(temp);
  /* return arrayToMatch.every(function(check){
    return check == temp;
   });*/
var bool;
   arrayToMatch.forEach(function(check){
    bool=(check == temp);
   })
  console.log(bool);
}
isUniform();


0

구분 된 크기와 체계적인 목록을 가진 또 다른 방법 :

배열 1 = [1,2,3]; array2 = [1,2,3];

function isEqual(){

    return array1.toString()==array2.toString();
}

0

배열을 세트로 변환하고 크기를 확인할 수 있습니다

원시적 배열 항목의 경우, 즉 number, string:

const isArrayWithEqualEntries = array => new Set(array).size === 1

동등성을 테스트 할 필드가있는 객체 배열의 경우 다음과 같이 말합니다 id.

const mapper = ({id}) => id
const isArrayWithEqualEntries = array => new Set(array.map(mapper)).size === 1

-4

PHP에는 매우 간단한 해결책이 있습니다.

(count (array_count_values ​​($ array)) == 1)

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

$arr1 = ['a', 'a', 'a', 'a'];
$arr2 = ['a', 'a', 'b', 'a'];


print (count(array_count_values($arr1)) == 1 ? "identical" : "not identical"); // identical
print (count(array_count_values($arr2)) == 1 ? "identical" : "not identical"); // not identical

그게 다야.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.