JS-配列脱重

19534 ワード

配列
ここでは要素のみを考慮して基本データタイプです.
[1,1,'1',2,'1'] => [1,'1',2]
方法1:二重循環
結果配列resには唯一の要素が含まれています.そして、arrの各要素は、resの各要素と比較します.等しい場合、内部循環から飛び出します.もし待たなければ、内部循環が終わったら、必ずj=res.lengthがあります.arr[i]を入れてください.
function unique(arr){
  var res = []
  for(var i=0;i<arr.length;i++){
    for(var j=0;j<res.length;j++){
      if(arr[i]===res[j])
        break
    }
    if(j==res.length){
      res.push(arr[i])
    }
  }
  return res
}
改善:二層循環のもう一つの方法はsplice方法を結合して、直接元の配列から重複要素を削除します.空の配列を作る必要がないです.個人的にはこの方法が上よりよく理解できると思います.
function unique(arr){
  for(var i=0;i<arr.length;i++){
    for(var j=i+1;j<arr.length;j++){
      if(arr[i]===arr[j]){
        arr.splice(j,1)  //splice        ,slice  
        j--  //       ,       j--
      }
    }
  }
  return arr
}
この2つの方法は大同小異で、いずれもNaNと対象に重いものではなく、他の基本データタイプは大丈夫です.
方法2:indexof改善
実はindexofを利用して方法の1の中の内部の循環を取り除いて、思想はまだ同じで、配列のincludes方法を使うことができます.
function unique(arr){
  var res = []
  for(var i=0;i<arr.length;i++){
    if(res.indexOf(arr[i])==-1){
      res.push(arr[i])
    }
  }
  return res
}
NaNと対象を重くしてはいけません.他の基本データタイプは大丈夫です.
修正:forエルゴード配列を使って、filter方法にも変えられます.元の配列を直接修正します.
function unique(arr){
  return arr.filter(function(cur,index){
    return arr.indexOf(cur) == index
  })
}
方法3:Objectキーの値は正しいです.
配列要素の値を対象とするobjのキー名は、オブジェクトのhasOwnProperty方法でobjがこのキーがあるかどうかを判断します.ない場合は、要素をresに入れますが、対象のキー名はすべて文字列で、配列要素1と'1'をキー名とする場合は同じです.
function unique(arr){
  var obj = {}
  var res = []
  for(var i=0;i<arr.length;i++){
    if(!obj.hasOwnProperty(typeof arr[i]+arr[i])){  //obj           
      res.push(arr[i])
      obj[typeof arr[i]+arr[i]] = true  //   typeof arr[i]+arr[i]
    }
  }
  return res
}
この方法はNaNを重くすることができて、対象は区別することができなくて、ただ一番前のあれだけを残します!任意の配列typeof arr[i]+arr[i]の結果は[object Object]であるからです.
方法4:ES 6セット/Mapデータ構造
Set—重複値のない配列
function unique(arr){
  return [...new Set(arr)]
}
Map-キーの名前は文字列の対象ではないことができて、mapを使うのは実は簡略化した方法3で、対象のキーの名前は更にタイプを加える必要がなくて、すべてのステップの意味は実はすべて同じです.
function unique(arr){
  var res = []
  var map = new Map()
  for(var i=0;i<arr.length;i++){
    if(!map.has(arr[i])){  //map        
      res.push(arr[i])
      map.set(arr[i],true)
    }
  }
  return res
}
この2つの方法は、NaNが重くなり、対象が重くなりません.他の基本データタイプは大丈夫です.
方法5:sort並び替え(限界があります)
配列sortの並べ替えに対して、同じ値が必ず続いています.配列を巡回して、現在の値が前の値と異なる場合、現在の値をresに入れます.
もし次のような状況があったら、正確な結果が得られないと思います.だから、sortは配列要素が全部数字/文字列の場合に使うべきだと思います.
var a = [1,1,2,'1',1,'1']
console.log(a.sort());  //[1,1,'1',1,'1',2]
function unique(arr){
  var sortedArr = arr.concat().sort()  //            ,       
  var res = []
  for (var i = 0; i < arr.length; i++){
    if(!i||sortedArr[i]!==sortedArr[i-1]){ //i=0 ,        
      res.push(sortedArr[i])
    }
  }
  return res
}

var array = ['1', '1', '1', '1', '2', '1']
console.log(unique(array)); //['1','2']