ฉันต้องการหาอาร์เรย์ที่ค่าทั้งหมดเท่ากัน วิธีที่เร็วที่สุดในการทำเช่นนี้คืออะไร? ฉันควรวนรอบมันและเปรียบเทียบค่าหรือไม่
['a', 'a', 'a', 'a'] // true
['a', 'a', 'b', 'a'] // false
a.join(',').split(a[0]).length === a.length + 1
ฉันต้องการหาอาร์เรย์ที่ค่าทั้งหมดเท่ากัน วิธีที่เร็วที่สุดในการทำเช่นนี้คืออะไร? ฉันควรวนรอบมันและเปรียบเทียบค่าหรือไม่
['a', 'a', 'a', 'a'] // true
['a', 'a', 'b', 'a'] // false
a.join(',').split(a[0]).length === a.length + 1
คำตอบ:
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()
วิธีทดสอบว่าองค์ประกอบทั้งหมดในอาร์เรย์ผ่านการทดสอบที่ใช้โดยฟังก์ชันที่มีให้หรือไม่
const everythings_equal = array => array.every(thing => thing === array[0]);
some
แทนevery
: arr.some( v => v !== arr[0] )
. arr[0]
นี้จะกลับต้นเมื่อองค์ประกอบแรกพบเป็นไปไม่เท่ากัน
every
ก็กลับมาก่อนเช่นกัน
แก้ไข:เป็นนินจาแดง:
!!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
ก่อน
false
! ตัวอย่างเช่นลอง [false, false, false] .reduce (ฟังก์ชั่น (a, b) {return (a === b)? a: false;});
["false", ""]
ส่งคืนtrue
: /
NaN
นี้สามารถนำขึ้นรอยโดยใช้ เนื่องจากทั้งคู่NaN === NaN
และNaN !== NaN
เป็นเท็จจึงรับประกันได้ว่าเมื่อprev
ตั้งค่าเป็น NaN แล้วไม่มีค่าใดสามารถนำออกมาได้ นอกจากนี้ยังเพิ่มในการปฏิเสธคู่แปลงผลลัพธ์ไปtrue
และfalse
เนื่องจากNaN
เป็นเท็จ รูปแบบสุดท้าย:!!array.reduce(function(a, b){ return (a === b) ? a : NaN; });
วิธีนี้ใช้ได้ผล คุณสร้างวิธีการบนอาร์เรย์โดยใช้แบบตัวอย่าง
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
Array.prototype
ปรับเพียงเล็กน้อย (แม้แต่ IE6) เป็นเพียงต้นแบบองค์ประกอบ DOM ที่ IE เวอร์ชันเก่าบางรุ่นไม่สนับสนุนการเพิ่ม
allValuesSame
ในวง
ใน JavaScript 1.6 คุณสามารถใช้Array.every
:
function AllTheSame(array) {
var first = array[0];
return array.every(function(element) {
return element === first;
});
}
คุณอาจต้องมีการตรวจสติอย่างเช่นเมื่ออาร์เรย์ไม่มีองค์ประกอบ (นอกจากนี้จะไม่ทำงานเมื่อองค์ประกอบทั้งหมดที่มีNaN
มาตั้งแต่NaN !== NaN
แต่ที่ไม่ควรจะเป็นปัญหา ... ใช่ไหม?)
คุณสามารถเปลี่ยน Array เป็นชุด ถ้าขนาดของ 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
ในกรณีนี้
และสำหรับการเปรียบเทียบประสิทธิภาพฉันยังทำมาตรฐาน:
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)
ดังนั้นจึงเห็นได้ชัดว่าการใช้ builtin array.some () เป็นวิธีที่เร็วที่สุดในการสุ่มตัวอย่าง
Array#some
บางครั้งมีประสิทธิภาพสูงกว่าก็คือเมื่อฟังก์ชั่นการโทรกลับส่งกลับจริงมันหยุดซ้ำ Array#every
ดังนั้นถ้าองค์ประกอบทั้งหมดที่อยู่ในความเป็นจริงเท่ากับการทำงานที่ควรจะเหมือนกับ และประสิทธิภาพสัมพัทธ์เมื่อองค์ประกอบทั้งหมดไม่เท่ากันจะแตกต่างกันไปตามดัชนีขององค์ประกอบที่ไม่ตรงกันแรก
คำตอบที่สั้นที่สุดโดยใช้ขีดล่าง / 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
แก้ไข:
หรือสั้นกว่านั้นก็ได้รับแรงบันดาลใจจากคำตอบของทอม:
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
หากคุณใช้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
จะเพียงพอแล้ว
ใช่คุณสามารถตรวจสอบได้โดยใช้ตัวกรองดังต่อไปนี้ง่ายมากตรวจสอบทุกค่าเหมือนกันกับค่าแรก:
//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
หรือคุณสามารถเพิ่มไปยังฟังก์ชัน Array ดั้งเดิมใน 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
คุณสามารถใช้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] )
ควรจะเป็น มิฉะนั้นคุณเพียงแค่การตรวจสอบว่าค่าใด ๆ เท่ากับครั้งแรกซึ่งจะแน่นอนเสมอจะเป็นจริง :)
some
แทนevery
ดังที่กล่าวไว้ในย่อหน้าแรก :) ขอบคุณสำหรับการจับ!
คุณสามารถรับหนึ่งซับเพื่อทำสิ่งที่คุณต้องการโดยใช้ฟังก์ชั่นArray.prototype.every , Object.isและ ES6:
const all = arr => arr.every(x => Object.is(arr[0], x));
ฉันคิดว่าวิธีที่ง่ายที่สุดในการทำเช่นนี้คือการสร้างลูปเพื่อเปรียบเทียบแต่ละค่ากับถัดไป ตราบใดที่มีการแบ่งใน "โซ่" แล้วมันจะกลับเท็จ หากครั้งแรกเท่ากับที่สองที่สองเท่ากับที่สามและอื่น ๆ แล้วเราสามารถสรุปได้ว่าองค์ประกอบทั้งหมดของอาร์เรย์จะมีค่าเท่ากัน
รับข้อมูลอาร์เรย์ [] จากนั้นคุณสามารถใช้:
for(x=0;x<data.length - 1;x++){
if (data[x] != data[x+1]){
isEqual = false;
}
}
alert("All elements are equal is " + isEqual);
arr.length && arr.reduce(function(a, b){return (a === b)?a:false;}) === arr[0];
อัปเดตโซลูชันใหม่: ตรวจสอบดัชนี
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));
}
คุณสามารถใช้สิ่งนี้:
function same(a) {
if (!a.length) return true;
return !a.filter(function (e) {
return e !== a[0];
}).length;
}
ฟังก์ชันจะตรวจสอบก่อนว่าอาเรย์นั้นว่างหรือไม่ หากเป็นค่าจะเท่ากับ .. มิฉะนั้นจะกรองอาร์เรย์และใช้องค์ประกอบทั้งหมดที่แตกต่างจากอาร์เรย์แรก หากไม่มีค่าดังกล่าว => อาร์เรย์จะมีองค์ประกอบเท่ากันมิฉะนั้นจะไม่มี
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);
}));
}
มันง่าย สร้างฟังก์ชั่นและส่งผ่านพารามิเตอร์ ในฟังก์ชั่นนั้นคัดลอกดัชนีแรกลงในตัวแปรใหม่ จากนั้นสร้างห่วงสำหรับและห่วงผ่านอาร์เรย์ ภายในลูปสร้างลูป while พร้อมเงื่อนไขการตรวจสอบว่าตัวแปรที่สร้างขึ้นใหม่นั้นมีค่าเท่ากับองค์ประกอบทั้งหมดในลูปหรือไม่ ถ้าผลตอบแทนเท่ากันเป็นจริงหลังจาก for for loop เสร็จสมบูรณ์มิฉะนั้นจะส่งคืน false ภายใน while loop
function isUniform(arra){
var k=arra[0];
for (var i = 0; i < arra.length; i++) {
while(k!==arra[i]){
return false;
}
}
return true;
}
ตอบรับการทำงานที่ดี แต่ฉันต้องการที่จะเพิ่มเล็กน้อย มันไม่ได้ผลสำหรับฉันที่จะใช้===
เพราะฉันกำลังเปรียบเทียบอาร์เรย์ของออบเจ็กต์อาร์เรย์อย่างไรก็ตามในแอพของฉันฉันใช้แพ็คเกจที่มีความลึกเท่ากันซึ่งฉันขอแนะนำ ด้วยรหัสของฉันดูเหมือนว่านี้:
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
}
]
]
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']));
และคุณก็ทำ!
ตอนนี้คุณสามารถใช้ประโยชน์จากชุดที่จะทำอย่างง่ายดาย
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);
คุณสามารถใช้วง for:
function isEqual(arr) {
var first = arr[0];
for (let i = 1; i < arr.length; i++) {
if (first !== arr[i]) {
return false;
}
}
return true;
}
นี่มันไม่ซับซ้อนจริงๆ ฉันสงสัยอย่างมากว่าคุณไม่ได้ลอง สิ่งที่คุณทำคือคุณเลือกค่าแรกบันทึกในตัวแปรจากนั้นภายในfor
ลูปให้เปรียบเทียบค่าที่ตามมาทั้งหมดกับค่าแรก
ฉันตั้งใจจะไม่แชร์รหัสใด ๆ ค้นหาวิธีการfor
ใช้งานและวิธีเปรียบเทียบตัวแปร
Simple one line solution เพียงเปรียบเทียบกับ array ที่เต็มไปด้วยรายการแรก
if(arr.join('') === Array(arr.length).fill(arr[0]).join(''))
อีกวิธีที่น่าสนใจเมื่อคุณใช้ไวยากรณ์ฟังก์ชั่นลูกศร 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
และเมื่อคุณไม่ต้องการใช้ตัวแปรสำหรับ array (x) อีกครั้ง:
!['a', 'a', 'a', 'a'].filter((e,i,a)=>e!==a[0])[0] // true
IMO ผู้โพสต์ก่อนหน้านี้ที่ใช้ array.every (... ) มีทางออกที่สะอาดที่สุด
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; }
}
}
สิ่งนี้อาจใช้งานได้คุณสามารถใช้รหัสความคิดเห็นออกเช่นกันซึ่งยังทำงานได้ดีกับฉากที่กำหนด
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();
อีกวิธีด้วยขนาดที่คั่นและรายการที่จัดระเบียบ:
array1 = [1,2,3]; array2 = [1,2,3];
function isEqual(){
return array1.toString()==array2.toString();
}
คุณสามารถแปลงอาร์เรย์เป็นชุดและตรวจสอบขนาดของมัน
ในกรณีของรายการอาร์เรย์ดั้งเดิมเช่น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
ใน PHP มีวิธีแก้ปัญหาที่ง่ายมากวิธีหนึ่งคือ
(นับ (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
นั่นคือทั้งหมดที่