JavaScript配列をチェックして、重複する値がないかどうかを確認する必要があります。これを行う最も簡単な方法は何ですか?重複する値が何であるかを見つける必要があるだけです-実際にはそれらのインデックスや重複する回数は必要ありません。
配列をループして他のすべての値をチェックして一致を確認できることはわかっていますが、もっと簡単な方法があるはずです。
JavaScript配列をチェックして、重複する値がないかどうかを確認する必要があります。これを行う最も簡単な方法は何ですか?重複する値が何であるかを見つける必要があるだけです-実際にはそれらのインデックスや重複する回数は必要ありません。
配列をループして他のすべての値をチェックして一致を確認できることはわかっていますが、もっと簡単な方法があるはずです。
回答:
配列を並べ替えて実行し、次の(または前の)インデックスが現在のインデックスと同じかどうかを確認できます。並べ替えアルゴリズムが適切であると仮定すると、これはO(n 2)未満である必要があります。
const findDuplicates = (arr) => {
let sorted_arr = arr.slice().sort(); // You can define the comparing function here.
// JS by default uses a crappy string compare.
// (we use slice to clone the array so the
// original array won't be modified)
let results = [];
for (let i = 0; i < sorted_arr.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
return results;
}
let duplicatedArray = [9, 9, 111, 2, 3, 4, 4, 5, 7];
console.log(`The duplicates in ${duplicatedArray} are ${findDuplicates(duplicatedArray)}`);
場合、あなたは重複のための関数として返すことになります。これは、同様のタイプのケースです。
arr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7];
i++
。代わりに、彼らは書きませんと言いますj = i + +j
。2つの異なるもの私見。私i += 1
はシンプルで美しいよりも混乱していると思いますi++
:)
var sorted_arr = arr.sort()
役に立たない:arr.sort()
元の配列を変更します(それ自体が問題です)。これにより、要素も破棄されます。(上記のコードを実行します。9はどうなりますか?)cc @dystroyよりクリーンな解決策はresults = arr.filter(function(elem, pos) { return arr.indexOf(elem) == pos; })
重複を排除したい場合は、この素晴らしい解決策を試してください:
function eliminateDuplicates(arr) {
var i,
len = arr.length,
out = [],
obj = {};
for (i = 0; i < len; i++) {
obj[arr[i]] = 0;
}
for (i in obj) {
out.push(i);
}
return out;
}
出典:http : //dreaminginjavascript.wordpress.com/2008/08/22/elimination-duplicates/
これは重複スレッド(!)からの私の答えです:
このエントリ2014を作成したとき-すべての例はforループまたはjQueryでした。Javascriptには、このための完璧なツールがあります。並べ替え、マッピング、縮小です。
var names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']
var uniq = names
.map((name) => {
return {
count: 1,
name: name
}
})
.reduce((a, b) => {
a[b.name] = (a[b.name] || 0) + b.count
return a
}, {})
var duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1)
console.log(duplicates) // [ 'Nancy' ]
@ Dmytro-Laptinは、いくつかのコードコードが削除されることを指摘しました。これは、同じコードのよりコンパクトなバージョンです。ES6のいくつかのトリックと高次関数を使用する:
const names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']
const count = names =>
names.reduce((a, b) => ({ ...a,
[b]: (a[b] || 0) + 1
}), {}) // don't forget to initialize the accumulator
const duplicates = dict =>
Object.keys(dict).filter((a) => dict[a] > 1)
console.log(count(names)) // { Mike: 1, Matt: 1, Nancy: 2, Adam: 1, Jenny: 1, Carl: 1 }
console.log(duplicates(count(names))) // [ 'Nancy' ]
これは、配列内の重複する値を実際に見つける最も短い方法の1つです。OPから特に求められたように、これは重複を削除するのではなく、それらを見つけます。
var input = [1, 2, 3, 1, 3, 1];
var duplicates = input.reduce(function(acc, el, i, arr) {
if (arr.indexOf(el) !== i && acc.indexOf(el) < 0) acc.push(el); return acc;
}, []);
document.write(duplicates); // = 1,3 (actual array == [1, 3])
これには、並べ替えやサードパーティのフレームワークは必要ありません。また、手動ループも必要ありません。これは、indexOf()(またはより明確に言うと、厳密な比較演算子)がサポートするすべての値で機能します。
reduce()のためと)のindexOf(それは少なくともIE 9で必要です。
const dupes = items.reduce((acc, v, i, arr) => arr.indexOf(v) !== i && acc.indexOf(v) === -1 ? acc.concat(v) : acc, [])
この関数を追加するか、微調整してJavascriptのArrayプロトタイプに追加できます。
Array.prototype.unique = function () {
var r = new Array();
o:for(var i = 0, n = this.length; i < n; i++)
{
for(var x = 0, y = r.length; x < y; x++)
{
if(r[x]==this[i])
{
alert('this is a DUPE!');
continue o;
}
}
r[r.length] = this[i];
}
return r;
}
var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,9];
var unique = arr.unique();
alert(unique);
更新:以下は、最適化された組み合わせ戦略を使用しています。プリミティブルックアップを最適化して、ハッシュO(1)ルックアップ時間のメリットを享受します(unique
プリミティブの配列で実行するとO(n)になります)。オブジェクトのルックアップは、反復処理中にオブジェクトに一意のIDのタグを付けることで最適化されるため、重複オブジェクトの識別もアイテムごとにO(1)、リスト全体に対してO(n)になります。唯一の例外は凍結されたアイテムですが、それらはまれであり、配列とindexOfを使用してフォールバックが提供されます。
var unique = function(){
var hasOwn = {}.hasOwnProperty,
toString = {}.toString,
uids = {};
function uid(){
var key = Math.random().toString(36).slice(2);
return key in uids ? uid() : uids[key] = key;
}
function unique(array){
var strings = {}, numbers = {}, others = {},
tagged = [], failed = [],
count = 0, i = array.length,
item, type;
var id = uid();
while (i--) {
item = array[i];
type = typeof item;
if (item == null || type !== 'object' && type !== 'function') {
// primitive
switch (type) {
case 'string': strings[item] = true; break;
case 'number': numbers[item] = true; break;
default: others[item] = item; break;
}
} else {
// object
if (!hasOwn.call(item, id)) {
try {
item[id] = true;
tagged[count++] = item;
} catch (e){
if (failed.indexOf(item) === -1)
failed[failed.length] = item;
}
}
}
}
// remove the tags
while (count--)
delete tagged[count][id];
tagged = tagged.concat(failed);
count = tagged.length;
// append primitives to results
for (i in strings)
if (hasOwn.call(strings, i))
tagged[count++] = i;
for (i in numbers)
if (hasOwn.call(numbers, i))
tagged[count++] = +i;
for (i in others)
if (hasOwn.call(others, i))
tagged[count++] = others[i];
return tagged;
}
return unique;
}();
ES6コレクションが利用可能な場合は、はるかにシンプルで大幅に高速なバージョンがあります。(IE9 +およびその他のブラウザーのシム:https : //github.com/Benvie/ES6-Harmony-Collections-Shim)
function unique(array){
var seen = new Set;
return array.filter(function(item){
if (!seen.has(item)) {
seen.add(item);
return true;
}
});
}
更新:重複を取得する短いワンライナー:
[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) !== i) // [2, 4]
重複なしで配列を取得するには、単に条件を反転させます。
[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) === i) // [1, 2, 3, 4]
filter()
以下の私の古い答えでは単に考えませんでした;)
あなたが必要なのは、この質問で尋ねられたように重複がないことを確認することだけである場合、every()
メソッドを使用できます:
[1, 2, 3].every((e, i, a) => a.indexOf(e) === i) // true
[1, 2, 1].every((e, i, a) => a.indexOf(e) === i) // false
ご了承ください every()
IE 8以下は動作しないて。
var a = ["a","a","b","c","c"];
a.filter(function(value,index,self){ return (self.indexOf(value) !== index )})
'a'
in array、inside filter function the index == 1
一方、self.indexOf('a') == 0
これはあなたが欲しいものを手に入れるはずです、ただの複製です。
function find_duplicates(arr) {
var len=arr.length,
out=[],
counts={};
for (var i=0;i<len;i++) {
var item = arr[i];
counts[item] = counts[item] >= 1 ? counts[item] + 1 : 1;
if (counts[item] === 2) {
out.push(item);
}
}
return out;
}
find_duplicates(['one',2,3,4,4,4,5,6,7,7,7,'pig','one']); // -> ['one',4,7] in no particular order.
// 🚩🚩 🚩 🚩
var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,22],
arr2 = [1,2,511,12,50],
arr3 = [22],
unique;
// Combine all the arrays to a single one
unique = arr.concat(arr2, arr3)
// create a new (dirty) Array with only the unique items
unique = unique.map((item,i) => unique.includes(item, i+1) ? item : '' )
// Cleanup - remove duplicate & empty items items
unique = [...new Set(unique)].filter(n => n)
console.log(unique)
Array.prototype.unique = function () {
var arr = this.sort(), i; // input must be sorted for this to work
for( i=arr.length; i--; )
arr[i] === arr[i-1] && arr.splice(i,1); // remove duplicate item
return arr;
}
var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,9],
arr2 = [1,2,511,12,50],
arr3 = [22],
// merge arrays & call custom Array Prototype - "unique"
unique = arr.concat(arr2, arr3).unique();
console.log(unique); // [22, 50, 12, 511, 2, 1, 9, 5, 8, 7, 3, 6, 4]
if (!Array.prototype.indexOf){
Array.prototype.indexOf = function(elt /*, from*/){
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0) ? Math.ceil(from) : Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++){
if (from in this && this[from] === elt)
return from;
}
return -1;
};
}
if( $.inArray(this[i], arr) == -1 )
追加する代わりに Array.prototype.indexOf
var r = [];
コードを機能させるために、初期化する必要がありました。そして魅力のように働いた。
r
変数は必要ありません
これが私の簡単な1行のソリューションです。
最初に一意の要素ではなく、次にSetを使用して見つかった配列を一意にします。
したがって、最後に重複の配列があります。
var array = [1, 2, 2, 3, 3, 4, 5, 6, 2, 3, 7, 8, 5, 22, 1, 2, 511, 12, 50, 22];
console.log([...new Set(
array.filter((value, index, self) => self.indexOf(value) !== index))]
);
これは私の提案です(ES6):
let a = [1, 2, 3, 4, 2, 2, 4, 1, 5, 6]
let b = [...new Set(a.sort().filter((o, i) => o !== undefined && a[i + 1] !== undefined && o === a[i + 1]))]
// b is now [1, 2, 4]
undefined
重複していることを報告します。
var a = [324,3,32,5,52,2100,1,20,2,3,3,2,2,2,1,1,1].sort();
a.filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});
または配列のprototyp.chainに追加されたとき
//copy and paste: without error handling
Array.prototype.unique =
function(){return this.sort().filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});}
i&&
配列の境界から外れないようにするためだと思いますが、これは、ソートされた配列の最初の要素が含まれないことも意味します。あなたの例では1
、結果の配列にはありません。つまりは、return i&&v!==o[i-1]?v:0;
あるべきreturn v!==o[i-1];
es6オブジェクトの構造化と削減を使用した高速でエレガントな方法
O(n)(配列の1回の反復)で実行され、2回以上出現する値を繰り返しません。
const arr = ['hi', 'hi', 'hi', 'bye', 'bye', 'asd']
const {
dup
} = arr.reduce(
(acc, curr) => {
acc.items[curr] = acc.items[curr] ? acc.items[curr] += 1 : 1
if (acc.items[curr] === 2) acc.dup.push(curr)
return acc
}, {
items: {},
dup: []
},
)
console.log(dup)
// ['hi', 'bye']
これが私が考えることができる最も簡単な解決策です:
const arr = [-1, 2, 2, 2, 0, 0, 0, 500, -1, 'a', 'a', 'a']
const filtered = arr.filter((el, index) => arr.indexOf(el) !== index)
// => filtered = [ 2, 2, 0, 0, -1, 'a', 'a' ]
const duplicates = [...new Set(filtered)]
console.log(duplicates)
// => [ 2, 0, -1, 'a' ]
それでおしまい。
注意:
0
、文字列、負の数を含む任意の数値で動作します。例:-1
-
関連する質問: JavaScript配列内のすべての一意の値を取得します(重複を削除します)
元の配列arr
は保持されfilter
ます(元の配列を変更する代わりに新しい配列を返します)
filtered
配列は含まれ、すべての重複を。それができるにも(ここで私たちのフィルタ配列を例えば1つの以上同じ値が含まれています[ 2, 2, 0, 0, -1, 'a', 'a' ]
)
重複している値のみを取得したい場合(同じ値で複数の重複をしたくない場合)を使用できます[...new Set(filtered)]
(ES6には、一意の値のみを格納できるオブジェクトセットがあります)
お役に立てれば。
これは非常に軽くて簡単な方法です:
var codes = dc_1.split(',');
var i = codes.length;
while (i--) {
if (codes.indexOf(codes[i]) != i) {
codes.splice(i,1);
}
}
ES6では(またはBabelまたはTypesciptを使用して)、次の操作を簡単に実行できます。
var duplicates = myArray.filter(i => myArray.filter(ii => ii === i).length > 1);
ES6構文を使用した単純なコード(ソートされた重複の配列を返す):
let duplicates = a => {d=[]; a.sort((a,b) => a-b).reduce((a,b)=>{a==b&&!d.includes(a)&&d.push(a); return b}); return d};
使い方:
duplicates([1,2,3,10,10,2,3,3,10]);
一発ギャグ
var arr = [9,1,2,4,3,4,9]
console.log(arr.filter((ele,indx)=>indx!==arr.indexOf(ele))) //get the duplicates
console.log(arr.filter((ele,indx)=>indx===arr.indexOf(ele))) //remove the duplicates
indx!
最初の例では何をしますか?
indx !== ...
-厳密な不平等。
result.filter((ele,indx) => indx !== result.map(e => e.name).indexOf(ele.name));
この答えも役立つかもしれません。js reduce
演算子/メソッドを利用して、配列から重複を削除します。
const result = [1, 2, 2, 3, 3, 3, 3].reduce((x, y) => x.includes(y) ? x : [...x, y], []);
console.log(result);
new Set([1, 2, 2, 3, 3, 3, 3])
重複を削除するためだけにできるようになりました
次の関数(すでに述べたexcludeDuplicates関数のバリエーション)は、入力["test"、 "test2"、 "test2"、1、1、1、2に対してtest2,1,7,5を返すトリックを行うようです、3、4、5、6、7、7、10、22、43、1、5、8]
JavaScript配列はほとんど何でも保持できるため、JavaScriptの問題は他のほとんどの言語よりも奇妙であることに注意してください。並べ替えを使用するソリューションでは、適切な並べ替え機能を提供する必要がある場合があることに注意してください。そのルートはまだ試していません。
この特定の実装は、(少なくとも)文字列と数値に対して機能します。
function findDuplicates(arr) {
var i,
len=arr.length,
out=[],
obj={};
for (i=0;i<len;i++) {
if (obj[arr[i]] != null) {
if (!obj[arr[i]]) {
out.push(arr[i]);
obj[arr[i]] = 1;
}
} else {
obj[arr[i]] = 0;
}
}
return out;
}
ES5のみ(つまり、IE8以下ではfilter()ポリフィルが必要です):
var arrayToFilter = [ 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3 ];
arrayToFilter.
sort().
filter( function(me,i,arr){
return (i===0) || ( me !== arr[i-1] );
});
var arr = [2, 1, 2, 2, 4, 4, 2, 5];
function returnDuplicates(arr) {
return arr.reduce(function(dupes, val, i) {
if (arr.indexOf(val) !== i && dupes.indexOf(val) === -1) {
dupes.push(val);
}
return dupes;
}, []);
}
alert(returnDuplicates(arr));
この関数は、並べ替えのステップを回避し、reduce()メソッドを使用して、重複がまだ存在しない場合は、新しい配列に複製をプッシュします。
これはおそらく 、ここにあるほとんどの関数よりも10倍高速に配列から重複を永久に削除する最も速い方法の1つです。&サファリでは78倍高速
function toUnique(a,b,c){//array,placeholder,placeholder
b=a.length;
while(c=--b)while(c--)a[b]!==a[c]||a.splice(c,1)
}
var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];
toUnique(array);
console.log(array);
上記のコードが読めない場合は、JavaScriptの本を読んでください。https://stackoverflow.com/a/21353032/2450730
編集
コメントで述べたように、この関数は一意の配列を返しますが、質問は重複を見つけるように求めます。その場合、この関数を簡単に変更すると、重複を配列にプッシュでき、前の関数を使用toUnique
すると、重複の重複が削除されます。
function theDuplicates(a,b,c,d){//array,placeholder,placeholder
b=a.length,d=[];
while(c=--b)while(c--)a[b]!==a[c]||d.push(a.splice(c,1))
}
var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];
toUnique(theDuplicates(array));
「includes」を使用して、要素がすでに存在するかどうかをテストします。
var arr = [1, 1, 4, 5, 5], darr = [], duplicates = [];
for(var i = 0; i < arr.length; i++){
if(darr.includes(arr[i]) && !duplicates.includes(arr[i]))
duplicates.push(arr[i])
else
darr.push(arr[i]);
}
console.log(duplicates);
<h3>Array with duplicates</h3>
<p>[1, 1, 4, 5, 5]</p>
<h3>Array with distinct elements</h3>
<p>[1, 4, 5]</p>
<h3>duplicate values are</h3>
<p>[1, 5]</p>
ES6は、基本的に重複を受け入れない配列であるSetデータ構造を提供します。Setデータ構造を使用すると、配列内の重複を見つける非常に簡単な方法があります(1つのループのみを使用)。
これが私のコードです
function findDuplicate(arr) {
var set = new Set();
var duplicates = new Set();
for (let i = 0; i< arr.length; i++) {
var size = set.size;
set.add(arr[i]);
if (set.size === size) {
duplicates.add(arr[i]);
}
}
return duplicates;
}
配列フィルターを使用してこれを実現する簡単な方法を見つけました
var list = [9, 9, 111, 2, 3, 4, 4, 5, 7];
// Filter 1: to find all duplicates elements
var duplicates = list.filter(function(value,index,self) {
return self.indexOf(value) !== self.lastIndexOf(value) && self.indexOf(value) === index;
});
console.log(duplicates);
以下のロジックはより簡単で高速になります
// @Param:data:Array that is the source
// @Return : Array that have the duplicate entries
findDuplicates(data: Array<any>): Array<any> {
return Array.from(new Set(data)).filter((value) => data.indexOf(value) !== data.lastIndexOf(value));
}
利点:
ロジックの説明:
注: map()およびfilter()メソッドは効率的で高速です。