JavaScript配列の重い6つの方法

5672 ワード

方法1
考えなくても、O(n^2)複雑度の解法が得られます.変数配列resの保存結果を定義します.巡回は、resの中に既に存在している場合、重複した要素であることを示します.ない場合は、resに入れます.
function unique(a) {
  var res = [];

  for (var i = 0, len = a.length; i < len; i++) {
    var item = a[i];

 for (var j = 0, jLen = res.length; j < jLen; j++) {
      if (res[j] === item)
        break;
    }

    if (j === jLen)
      res.push(item);
  }

  return res;
}

var a = [1, 1, '1', '2', 1];
var ans = unique(a);
console.log(ans); // => [1, "1", "2"]
コードはとても簡単です.もっと簡潔にしてもらえますか?ブラウザ互換性を考慮しないなら、ES 5が提供するAray.prototype.indexOf法でコードを簡略化できます.
function unique(a) {
  var res = [];

  for (var i = 0, len = a.length; i < len; i++) {
    var item = a[i];

    (res.indexOf(item) === -1) && res.push(item);
  }

  return res;
}

var a = [1, 1, '1', '2', 1];
var ans = unique(a);
console.log(ans); // => [1, "1", "2"]
indexOfを使った以上、filterを追加してもいいです.
function unique(a) {

  var res = a.filter(function(item, index, array) {
    return array.indexOf(item) === index;
  });
  
  return res;
}


var a = [1, 1, '1', '2', 1];
var ans = unique(a);
console.log(ans); // => [1, "1", "2"]
方法2
法1は、元の配列の要素と結果配列の要素を一つずつ比較し、考えを変えて、元の配列の重複要素の最後の要素を結果配列に入れることができます.
複雑さはまだO(n^2)ですが、1は配列の一番後ろに現れています.結果配列は元素の最後の出現の位置を取っています.
function unique(a) {

  var res = a.filter(function(item, index, array) {
    return array.indexOf(item) === index;
  });
  
  return res;
}


var a = [1, 1, '1', '2', 1];
var ans = unique(a);
console.log(ans); // => [1, "1", "2"]
方法三(sort)
筆記試験の面接で上記のようなO(n^2)の案しか答えられなかったら、まだ面接官を満足させることができないかもしれません.配列をsortで並べ替えると、理論的に同じ元素が隣の位置に置かれます.前後の位置の元素を比較すればいいです.
function unique(a) {
  return a.concat().sort().filter(function(item, pos, ary) {
    return !pos || item != ary[pos - 1];
  });
}


var a = [1, 1, 3, 2, 1, 2, 4];
var ans = unique(a);
console.log(ans); // => [1, 2, 3, 4]
ですが、問題がまた来ました.1と1は一緒に並べられます.異なるObjectは一緒に並べられます.これらのtostring()の結果が同じなので、このようなエラーが発生します.
function unique(a) {
  return a.concat().sort().filter(function(item, pos, ary) {
    return !pos || item != ary[pos - 1];
  });
}

var a = [1, 1, 3, 2, 1, 2, 4, '1'];
var ans = unique(a);
console.log(ans); // => [1, 2, 3, 4]
(もちろん、配列内に出現する可能性のあるさまざまなタイプに対して、この比較関数を書くことができます.でも、これはちょっと面倒なようです.)
方法四(object)
JavaScriptのObjectオブジェクトを使ってハッシュ表として使用します.これも数年前の筆記試験時の解法です.sortと同じように、完全にNumberの基本タイプからなる配列を重くすることができます.
function unique(a) {
  var seen = {};

  return a.filter(function(item) {
    return seen.hasOwnProperty(item) ? false : (seen[item] = true);
  });
}


var a = [1, 1, 3, 2, 1, 2, 4];
var ans = unique(a);
console.log(ans); // => [1, 3, 2, 4]
はまだ方法三と同じ問題です.Objectのkey値は全部Stringタイプですから、1と「1」の区別ができません.少し改善して、タイプもkeyに入れます.
function unique(a) {
  var ret = [];
  var hash = {};

  for (var i = 0, len = a.length; i < len; i++) {
    var item = a[i];

    var key = typeof(item) + item;

    if (hash[key] !== 1) {
      ret.push(item);
      hash[key] = 1;
    }
  }

  return ret;
}


var a = [1, 1, 3, 2, '4', 1, 2, 4, '1'];
var ans = unique(a);
console.log(ans); // => [1, 3, 2, "4", 4, "1"]
嫌な1と1の問題を解決しましたが、他の問題があります.
function unique(a) {
  var ret = [];
  var hash = {};

  for (var i = 0, len = a.length; i < len; i++) {
    var item = a[i];

    var key = typeof(item) + item;
function unique(a) {
  return Array.from(new Set(a));
}

var a = [{name: "hanzichi"}, {age: 30}, new String(1), new Number(1)];
var ans = unique(a);
console.log(ans); // => [Object, Object, String, Number]
if(hash[key]!==1){ret.push(item);hash[key]=1;}return ret;var a=「{name:"hanzchi"」、{age:30}、new String(1)、new Number(1)」;var ans=unique(a);consolone.log(ans)/=>[Object,String]
                  Number  ,           ! 
  

(ES6)

ES6 Set Array.from , ! , :

function unique(a) {
  return Array.from(new Set(a));
}

var a = [{name: "hanzichi"}, {age: 30}, new String(1), new Number(1)];
var ans = unique(a);
console.log(ans); // => [Object, Object, String, Number]
_.unique
にアンダースコアのこれに する を にきて、アンダースコアはこれを_にカプセル しました.uniqueメソッドでは、 び し は_.unique(array,[isSorted],[iteratee]). のパラメータは であり、 い が であり、 のパラメータはオプションであり、 が されていれば、ブール trueに ることができ、 のパラメータは であり、 の の を する があれば、 に ることができる. のデキストは== に づいています.
はとても で、アンダースコアの の は の と じです.
コアコードを に ました.
for (var i = 0, length = getLength(array); i < length; i++) {
  var value = array[i],
      //          
      //              
      computed = iteratee ? iteratee(value, i, array) : value;

  //        ,                 
  //   seen          
  if (isSorted) {
    //    i === 0,    push
    //                   
    if (!i || seen !== computed) result.push(value);
    // seen       ,      
    seen = computed;
  } else if (iteratee) {
    //    seen[]     computed      
    if (!_.contains(seen, computed)) {
      seen.push(computed);
      result.push(value);
    }
  } else if (!_.contains(result, value)) {  
    //             ,     seen[]    
    result.push(value);
  }
}
の の は を して、 に して、 が としているなら、 の と して、もし じならば、すでに れたことがあって、 の に しないで、さもなくば します. がある は、 の を し、 を にして び します.contains の は び しです.indexOf は、 の と じです.