ජාවාස්ක්‍රිප්ට් අරාව තුළ සියලු අද්විතීය අගයන් ලබා ගන්න (අනුපිටපත් ඉවත් කරන්න)


1534

මට අද්විතීය සංඛ්‍යාවක් ඇති බවට සහතික කර ගත යුතු සංඛ්‍යා සමූහයක් මා සතුව ඇත. මම පහත දැක්වෙන කේත ස්නිපටය අන්තර්ජාලයේ සොයා ගත් අතර අරාවෙහි ශුන්‍යයක් ඇති වන තෙක් එය විශිෂ්ට ලෙස ක්‍රියා කරයි. මෙම අනෙක් ස්ක්‍රිප්ට් එක ස්ටැක් පිටාර ගැලීමෙන් මට හමු විය, එය හරියටම පාහේ පෙනේ, නමුත් එය අසාර්ථක නොවේ.

ඉතින් මට ඉගෙන ගැනීමට උදව් කිරීම සඳහා, මූලාකෘති පිටපත වැරදී ඇත්තේ කොතැනදැයි තීරණය කිරීමට මට උදව් කළ හැකිද?

Array.prototype.getUnique = function() {
 var o = {}, a = [], i, e;
 for (i = 0; e = this[i]; i++) {o[e] = 1};
 for (e in o) {a.push (e)};
 return a;
}

අනුපිටපත් ප්‍රශ්නයෙන් තවත් පිළිතුරු:

සමාන ප්‍රශ්නය:


3
pphippietrail එම පැරණි ප්‍රශ්නය වන්නේ අනුපිටපත් පමණක් සොයා ගැනීම සහ ආපසු ලබා දීමයි (මා ද ව්‍යාකූල විය!). අරාවෙහි ශුන්‍යයක් ඇති විට මෙම ශ්‍රිතය අසමත් වන්නේ මන්ද යන්න පිළිබඳව මගේ ප්‍රශ්නය වැඩිය.
මෝටි

ඔබේ ප්‍රශ්න මාතෘකාව ද අපැහැදිලි කිරීමට ඔබට අවශ්‍ය විය හැකිය.
hippietrail

අනාගත පා readers කයින් සඳහා, ඔබේ දත්ත ව්‍යුහයේ අන්තර්ගතය නිතරම ඇල්ගොරිතමයෙන් වෙනස් කළ යුතු බව සොයා ගැනීමට පටන් ගත් විට, (ඒවා ඇණවුම් කරන්න, පුනරාවර්තන මූලද්‍රව්‍ය ඉවත් කරන්න, ආදිය) හෝ සෑම ක්‍රියාවලියකදීම එහි ඇතුළත ඇති මූලද්‍රව්‍ය සෙවීම, ඔබ යැයි සිතීම ආරක්ෂිතයි මුලින් වැරදි දත්ත ව්‍යුහය භාවිතා කරමින් අතෙහි ඇති කර්තව්‍යයට වඩාත් සුදුසු එකක් භාවිතා කිරීම ආරම්භ කරන්න (මේ අවස්ථාවේ දී අරාව වෙනුවට හැෂ් කට්ටලයක්).
නියුරෙටින්

මම කේතය වෙනත් තැනකින් පිටපත් කළා, බොහෝ කලකට පෙර ... නමුත් එය කෙළින්ම ඉදිරියට යන බවක් පෙනේ: o= object, a= array, i= indexසහ e= umm, යමක්: P
Mottie

Answers:


2740

ජාවාස්ක්‍රිප්ට් 1.6 / ඊසීඑම්එස්ක්‍රිප්ට් 5 සමඟ ඔබටfilter අද්විතීය අගයන් සහිත අරාවක් ලබා ගැනීම සඳහා පහත දැක්වෙන ආකාරයෙන් අරාවෙහි ස්වදේශීය ක්‍රමය භාවිතා කළ හැකිය :

function onlyUnique(value, index, self) { 
    return self.indexOf(value) === index;
}

// usage example:
var a = ['a', 1, 'a', 2, '1'];
var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']

ස්වදේශීය ක්‍රමය filterඅරාව හරහා ලූප වන අතර ලබා දී ඇති ඇමතුම් ආපසු ගැනීමේ ශ්‍රිතය පසු කරන ප්‍රවේශයන් පමණක් ඉතිරි වේ onlyUnique.

onlyUniqueපරික්ෂා කිරීම, දී ඇති අගය පළමු වරට සිදුවන්නේ නම්. එසේ නොවේ නම්, එය අනුපිටපතක් විය යුතු අතර එය පිටපත් නොකෙරේ.

මෙම විසඳුම jQuery හෝ prototype.js වැනි අමතර පුස්තකාලයක් නොමැතිව ක්‍රියා කරයි.

එය මිශ්‍ර වටිනාකම් සහිත අරා සඳහා ද ක්‍රියා කරයි.

දේශීය ක්රම සඳහා පහසුකම් සපයන්නේ නැත පැරණි වෙබ් බ්රව්සර (<ie9), සඳහා filterසහ indexOfඔබ වෙනුවෙන් MDN ලියකියවිලි වල වැඩ arounds සොයා ගත හැකි පෙරහන් හා indexOf .

ඔබ අගය පසුගිය සිදුවීමක් පවත්වා ගැනීමට ඔබට අවශ්ය නම්, සරල වෙනුවට indexOfවිසින් lastIndexOf.

ES6 සමඟ මෙය කෙටි කළ හැකිය:

// usage example:
var myArray = ['a', 1, 'a', 2, '1'];
var unique = myArray.filter((v, i, a) => a.indexOf(v) === i); 

// unique is ['a', 1, 2, '1']

අදහස් දැක්වීම ගැන කැමිලෝ මාටින්ට ස්තූතියි .

Setඅද්විතීය අගයන් ගබඩා කිරීම සඳහා ES6 හට ස්වදේශීය වස්තුවක් ඇත. අද්විතීය අගයන් සහිත අරාවක් ලබා ගැනීම සඳහා ඔබට දැන් මෙය කළ හැකිය:

var myArray = ['a', 1, 'a', 2, '1'];

let unique = [...new Set(myArray)]; 

// unique is ['a', 1, 2, '1']

යන ඉදිකිරීමටත් SetArray වැනි iterable වස්තුව, ගත වන අතර පැතිර ක්රියාකරු ...මාලාවක් බවට නැවත කට්ටලයක් පරිණාමනය කිරීම. අදහස් දැක්වීමේ ඉඟිය සඳහා ලූකස් ලයිස්ට ස්තූතියි .


60
අවාසනාවකට මෙන් මෙම විසඳුම වඩා මන්දගාමී වනු ඇත. ඔබ දෙවරක්, එක් වරක් පෙරණයකින් සහ එක් වරක් දර්ශකය සමඟ
ජැක් ෆ්‍රැන්සන්

19
Ack ජැක් ෆ්‍රැන්සන් වඩා මන්දගාමීද? රෆායෙල්ගෙන් විසඳුම ? මිශ්‍ර වර්ගයේ අරා සඳහා රෆායෙල් විසඳුම ක්‍රියා නොකරයි. මගේ උදාහරණය සඳහා ['a', 1, 'a', 2, '1']ඔබට ලැබෙනු ['a', 1, 2]ඇත. නමුත් මෙය මා බලාපොරොත්තු වූ දෙයක් නොවේ. BTW, වඩා මන්දගාමී ඉතා සාපේක්ෂයි.
ටී ලින්ඩිග්

25
නූතන JS හි: .filter((v,i,a)=>a.indexOf(v)==i)(මේද ඊතල අංකනය).
කැමිලෝ මාටින්


5
පළමුවෙන් වර්ග කිරීම සහ විවිධ දත්ත වර්ග සමඟ ගනුදෙනු කිරීම වැනි බොහෝ හැකියාවන් ඇතුළුව වඩාත් සවිස්තරාත්මක පිළිතුරක් සඳහා - stackoverflow.com/a/9229821/368896
ඩෑන් නිසෙන්බෝම්

908

ES6 / ES2015 සඳහා යාවත්කාලීන කළ පිළිතුර : කට්ටලය භාවිතා කරමින් තනි පේළි විසඳුම:

var items = [4,5,4,6,3,4,5,2,23,1,4,4,4]
var uniqueItems = Array.from(new Set(items))

කුමන ප්‍රතිලාභද

[4, 5, 6, 3, 2, 23, 1]

ලෙස le_m යෝජනා, මෙය භාවිතා කෙටි කළ හැකි පැතිර ක්රියාකරු , වැනි

var uniqueItems = [...new Set(items)]

12
සැලකිල්ලට ගන්න, එම අභ්‍යන්තර අරාව ක්‍රියා නොකරනු ඇතArray.from(new Set([[1,2],[1,2],[1,2,3]]))
ඇලෙක්සැන්ඩර් ගොන්චරොව්

3
සාපේක්ෂව මෙම විසඳුමේ කාර්ය සාධනය myArray.filter((v, i, a) => a.indexOf(v) === i);?
සිමෝයිව්

44
ඔබ Setප්‍රාථමික අගයන් වෙනුවට වස්තු එකතු කර එකතු කරන්නේ නම් එහි වස්තූන් සඳහා අද්විතීය යොමු කිරීම් අඩංගු වන බව කරුණාවෙන් සලකන්න . මේ අනුව, කට්ටලය sමෙය let s = new Set([{Foo:"Bar"}, {Foo:"Bar"}]);නැවත ලබා දෙනු ඇත: Set { { Foo: 'Bar' }, { Foo: 'Bar' } }එය Setඑකම අගයන් අඩංගු වස්තූන් සඳහා අද්විතීය වස්තු යොමු කිරීම් සහිත වේ. ඔබ ලිවීමට නම් let o = {Foo:"Bar"};සහ දෙදෙනෙකු සමග මාලාවක් නිර්මාණය යොමු එසේ වගේ: let s2 = new Set([o,o]);, එවිට s2 වනු ඇතSet { { Foo: 'Bar' } }
mortb

2
මෙම විකල්ප දෙකටම IE10 හි ගැටළු ඇති අතර පොලිෆිල්.ඕ ස්තරයක් තිබියදීත්
තයිමීන්

2
නව අත්හදා බැලීමක් jsperf.com/array-filter-unique-vs-new-set/1 වගේ new Setගේ කුසලානය
shuk

180

හැකි විසඳුම් 4 කට මම සියලු පිළිතුරු බෙදුවෙමි:

  1. { }අනුපිටපත් වැළැක්වීමට වස්තුව භාවිතා කරන්න
  2. උපකාරක අරාව භාවිතා කරන්න [ ]
  3. භාවිත filter + indexOf
  4. පාරිතෝෂිකය! ES6 Setsක්‍රමය.

පිළිතුරු වලින් සොයාගත් නියැදි කේත මෙන්න:

{ }අනුපිටපත් වැළැක්වීමට වස්තුව භාවිතා කරන්න

function uniqueArray1( ar ) {
  var j = {};

  ar.forEach( function(v) {
    j[v+ '::' + typeof v] = v;
  });

  return Object.keys(j).map(function(v){
    return j[v];
  });
} 

උපකාරක අරාව භාවිතා කරන්න [ ]

function uniqueArray2(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.push(arr[i]);
    return a;
}

භාවිත filter + indexOf

function uniqueArray3(a) {
  function onlyUnique(value, index, self) { 
      return self.indexOf(value) === index;
  }

  // usage
  var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']

  return unique;
}

ES6 භාවිතා කරන්න [...new Set(a)]

function uniqueArray4(a) {
  return [...new Set(a)];
}

මම කල්පනා කළා කුමන එක වේගවත්ද කියලා. කාර්යයන් පරීක්ෂා කිරීම සඳහා මම නියැදිය ගූගල් ෂීට් සාදා ඇත. සටහන: ECMA 6 ගූගල් ෂීට් වල ලබා ගත නොහැක, එබැවින් මට එය පරීක්ෂා කළ නොහැක.

පරීක්ෂණවල ප්‍රති result ලය මෙන්න: රූප විස්තරය මෙහි ඇතුළත් කරන්න

වස්තුව භාවිතා කරන කේතය { }හැෂ් භාවිතා කරන බැවින් එය ජය ගනු ඇතැයි මම අපේක්ෂා කළෙමි . එබැවින් ක්‍රෝම් සහ අයිඊ හි මෙම ඇල්ගොරිතම සඳහා හොඳම ප්‍රති results ල පරීක්ෂණ මගින් පෙන්වීම ගැන මම සතුටු වෙමි. කේතය සඳහා @rab ට ස්තූතියි .

යාවත්කාලීන කිරීම 2020

ගූගල් ස්ක්‍රිප්ට් ES6 එන්ජිම සක්‍රීය කර ඇත. දැන් මම අවසාන කේතය පරීක්ෂා කළ Setsඅතර එය වස්තු ක්‍රමයට වඩා වේගයෙන් දර්ශනය විය.


අයිතම 100.000 ට වඩා වැඩි අරා වල "filter + indexOf" විකල්පය අතිශයින් මන්දගාමී වේ. මට "වස්තු සිතියම" ප්‍රවේශය භාවිතා කිරීමට සිදු වුවද එය මුල් වර්ග කිරීම බිඳ දමයි.
ලිබර්බර්න්

වැඩි සංඛ්‍යාවක් මන්දගාමීද, වේගවත් නොවේද?
fletchsod

3
le fletchsod, සංඛ්‍යා යනු කේතය ක්‍රියාත්මක කිරීමට ms හි කාලයයි.
මැක්ස් මක්‍රොව්

1
ඉලක්කම් වොන්! ගූගල් යෙදුම් ස්ක්‍රිප්ට් ක්‍රියාත්මක වන්නේ සේවාදායකයාගේ බ්‍රව්සරයේ නොව ඔවුන්ගේ සේවාදායකයේ ය - එබැවින් ක්‍රෝම් / අයිඊ (හෝ පාහේ ඕනෑම බ්‍රව්සරයක) ක්‍රියාකාරීත්වය සමාන වේ!
ජේ දාදානියා

1
අතර එය කළ හැකි වේ ගූගල් කේත රචනය සේවාග්රාහකයා-පැත්තේ JS ක්රියාත්මක කිරීමට (එක්කෝ හරහා google.script.host හෝ google.script.run - වග බලා ගන්න නොවන), පිළිතුර පැහැදිලිව ප්රකාශ කරන්නේ "Google පත්ර තුළ ECMA 6 avaliable නොවේ" - ඒ නිසා පෝස්ටරය මේ සඳහා සේවාදායක පාර්ශවීය ගූගල් ස්ක්‍රිප්ට් භාවිතා කළ බව අපට ආරක්ෂිතව උපකල්පනය කළ හැකිය - මේ අනුව පිළිතුරෙන් පෙන්නුම් කරන්නේ බ්‍රව්සරයේ නොව ගූගල් සේවාදායකයේ ක්‍රියාකාරිත්වයයි !!
ජේ දාදානියා

138

ඔබට underscore.js ද භාවිතා කළ හැකිය .

console.log(_.uniq([1, 2, 1, 3, 1, 4]));
<script src="http://underscorejs.org/underscore-min.js"></script>

එය නැවත පැමිණේ:

[1, 2, 3, 4]

22
කරුණාකර මේ අය කරන්න. අරා මූලාකෘතියට යමක් සම්බන්ධ නොකරන්න. කරුණාකර.
ජේකබ් ඩෝල්ටන්

5
A ජාකොබ් ඩෝල්ටන් - මෙය අරේ මූලාකෘතිය දිගු නොකරයි. එය _ වස්තුවෙහි නම් කර ඇත.
superluminary

25
up සුපර්ලුමිනරි මම දන්නවා ඒකයි මම කිව්වේ කරුණාකරලා මේක කරන්න කියලා . පිළිගත් විසඳුම මඟින් අරේ මූලාකෘතිය වෙනස් කිරීම යෝජනා කරයි. ඒක කරන්න එපා.
ජේකබ් ඩෝල්ටන්

24
A ජාකොබ් ඩෝල්ටන් කරුණාකර මෙය නොකරන්න. කළ හැකි කුඩා රැකියාවක් සඳහා අමතර පුස්තකාලයක් එක් කිරීමට අවශ්‍ය නැතarray = [...new Set(array)]

3
මෙය ES විශේෂාංග භාවිතා කිරීමේ පරමාර්ථය පරාජය කළ අතර තවත් පුස්තකාල එකතු කිරීමෙන් වෙබ් අඩවිය තව තවත් පුපුරා යයි.
fletchsod

70

එක් ලයිනර්, පිරිසිදු ජාවාස්ක්‍රිප්ට්

ES6 සින්ටැක්ස් සමඟ

list = list.filter((x, i, a) => a.indexOf(x) == i)

x --> item in array
i --> index of item
a --> array reference, (in this case "list")

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ES5 සින්ටැක්ස් සමඟ

list = list.filter(function (x, i, a) { 
    return a.indexOf(x) == i; 
});

බ්‍රව්සර් අනුකූලතාව : IE9 +


14
PSpets එයට චතුරස්රාකාර පිරිවැයක් ඇත, එබැවින් එය හොඳම පිළිතුර නොවේ
ඔරියෝල්

Un සියලු අද්විතීය / විශේෂයන් මෙන් ස්පෙට්ස් ... ඔව්, බුද්ධිමත් වන්න, පළමුවෙන් වර්ග කිරීම සඳහා රේඩික්ස් භාවිතා කරන්න, බොහෝ අවස්ථාවන්හි 0 (n2) ඉක්මන් සෙවුමට වඩා මන්දගාමී වන්න.
doker

ස්තූතියි යාලුවනේ! මම මුලින්ම කේතය දෙස බැලූ විට එය වටහා නොගත් නමුත් දැන් එය ටිකක් පැහැදිලිව පෙනේ.
ස්පෙට්ස්

53

මම එතැන් සිට jQuery භාවිතා කරන හොඳ ක්‍රමයක් සොයාගෙන ඇත

arr = $.grep(arr, function(v, k){
    return $.inArray(v ,arr) === k;
});

සටහන: මෙම කේතය පෝල් අයිරිෂ්ගේ තාරා පන්ච් පෝස්ට් එකෙන් ඇද ගන්නා ලදි - මට ණය දීමට අමතක විය: පී


8
සංක්ෂිප්ත විසඳුමක්, නමුත් inArray ඇමතීම hasOwnProperty ඇමතීමට වඩා කාර්යක්ෂම නොවේ.
මිස්ටර් ස්මිත්

මෙයද O (N ^ 2) නේද? ශබ්ද කෝෂය හෝ hasOwnProperty ප්‍රවේශය O (N * logN) විය හැකිය.
වේග ගුවන් යානය

ඉන්ටර්නෙට් එක්ස්ප්ලෝරර් වීමට මෙය සහාය විය.
kerl

52

ES6 සමඟ කෙටිම විසඳුම: [...new Set( [1, 1, 2] )];

හෝ ඔබට අරේ මූලාකෘතිය වෙනස් කිරීමට අවශ්‍ය නම් (මුල් ප්‍රශ්නයේදී මෙන්):

Array.prototype.getUnique = function() {
    return [...new Set( [this] )];
};

EcmaScript 6 නවීන බ්‍රව්සර්වල මේ මොහොතේ (2015 අගෝස්තු) අර්ධ වශයෙන් පමණක් ක්‍රියාත්මක වන නමුත් ES6 (සහ ES7 පවා) නැවත ES5 වෙත ප්‍රවාහනය කිරීම සඳහා බාබෙල් ඉතා ජනප්‍රිය වී තිබේ. ඒ ආකාරයෙන් ඔබට අද ES6 කේතය ලිවිය හැකිය!

එහි ...තේරුම කුමක්දැයි ඔබ කල්පනා කරන්නේ නම්, එය පැතිරීමේ ක්‍රියාකරු ලෙස හැඳින්වේ . එම්ඩීඑන් වෙතින් : multiple බහු තර්ක (ක්‍රියාකාරී ඇමතුම් සඳහා) හෝ බහු මූලද්‍රව්‍ය (අරා වචනාර්ථ සඳහා) අපේක්ෂා කරන ස්ථානවල ප්‍රකාශනය පුළුල් කිරීමට පැතිරීමේ ක්‍රියාකරු ඉඩ දෙයි ». කට්ටලයක් නැවත ක්‍රියාත්මක කළ හැකි නිසා (සහ අද්විතීය අගයන් පමණක් තිබිය හැක), පැතිරීමේ ක්‍රියාකරු අරාව පිරවීම සඳහා කට්ටලය පුළුල් කරයි.

ES6 ඉගෙනීම සඳහා සම්පත්:


3
ඔබට එය ඊටත් වඩා කෙටි කළ හැකිය a = [...Set(a)], නමුත්, කෙසේ වෙතත්, මෙය ෆයර්ෆොක්ස් පමණි, දැනට.
c69

69 c69, හරි, ඊට වඩා කෙටි නොවනු ඇත. SpiderMonkey භාවිතා කරන්නන් ද අගය කරනු ඇත.
ටොරස්ටන් බෙකර්

බාබෙල් සමඟ වැඩ කරයි. ඔබට Array.from shim ද ඇතුළත් කළ යුතුය:require ( "core-js/fn/array/from" );
Vladislav Rastrusny

එය Array.prototype.getUnique = ශ්‍රිතය () {ආපසු [... නව කට්ටලය ([මෙය])] විය යුතුද; }; හෝ, Array.prototype.getUnique = ශ්‍රිතය () {ආපසු [... නව කට්ටලය (මෙය)]; }; මම එය පහත දැක්වෙන $ ('ශරීරය') මත යෙදුවෙමි. Html () .ලවර් කේස් (). ගැලපීම (/ ([a-zA-Z0-9 ._ + -] + @ [a-zA-Z0-9. _-] + \. [a-zA-Z0-9 ._-] +) / gi) .getUnique (); පළමුවැන්න මට එක් අද්විතීය වටිනාකමක් ලබා දුන්නේ දෙවැන්න ඉවත් කළ අනුපිටපත් නැවත ලබා ගත් තැන පමණි.
ashique

[...Set(['a', 1, 'a', 2, '1'])]TypeError එකක් විසි කරයි, එබැවින් එය රඳවා තබා ගැනීම තවමත් wise ානවන්ත ය new:[...new Set(['a', 1, 'a', 2, '1'])]
ඇඩම් කැට්ස්

37

සරලම විසඳුම:

var arr = [1, 3, 4, 1, 2, 1, 3, 3, 4, 1];
console.log([...new Set(arr)]);

හෝ:

var arr = [1, 3, 4, 1, 2, 1, 3, 3, 4, 1];
console.log(Array.from(new Set(arr)));


4
IE10 සහ ඊට පහළින් මෙය සහාය නොදක්වන බව සලකන්න. IE11 + සහ සෆාරි ඉදිරිපත් සීමා සහයෝගය (පවා වග බලා ගන්න ඉහත සඳහන් උදාහරණය කෘති) ඒ සටහන developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
oriadam

33

මෙය කළ හැකි සරලම හා වේගවත්ම (ක්‍රෝම් භාෂාවෙන්):

Array.prototype.unique = function() {
    var a = [];
    for (var i=0, l=this.length; i<l; i++)
        if (a.indexOf(this[i]) === -1)
            a.push(this[i]);
    return a;
}

අරාවෙහි ඇති සෑම අයිතමයක් හරහාම සරලවම ගමන් කරයි, එම අයිතමය දැනටමත් ලැයිස්තුවේ තිබේදැයි පරීක්ෂා කරයි, එය එසේ නොවේ නම්, ආපසු ලැබෙන අරාව වෙත තල්ලු කරන්න.

JsPerf ට අනුව, මෙම ශ්‍රිතය මට ඕනෑම තැනක සොයාගත හැකි වේගවත්ම වේ - ඔබේම දෑ එකතු කිරීමට නිදහස් වන්න.

මූලාකෘති නොවන අනුවාදය:

function uniques(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.push(arr[i]);
    return a;
}

වර්ග කිරීම

අරාව වර්ග කිරීමට අවශ්‍ය වූ විට, පහත දැක්වෙන්නේ වේගවත්ම ය:

Array.prototype.sortUnique = function() {
    this.sort();
    var last_i;
    for (var i=0;i<this.length;i++)
        if ((last_i = this.lastIndexOf(this[i])) !== i)
            this.splice(i+1, last_i-i);
    return this;
}

හෝ මූලාකෘති නොවන:

function sortUnique(arr) {
    arr.sort();
    var last_i;
    for (var i=0;i<arr.length;i++)
        if ((last_i = arr.lastIndexOf(arr[i])) !== i)
            arr.splice(i+1, last_i-i);
    return arr;
}

මෙය බොහෝ ක්‍රෝම් නොවන බ්‍රව්සර්වල ඉහත ක්‍රමයට වඩා වේගවත් වේ .


ලිනක්ස් හි, ක්‍රෝම් 55.0.2883 ඔබේ arr.unique () ට වැඩි කැමැත්තක් දක්වන අතර ස්විලියම්ස්ගේ arrclone2.sortFilter () මන්දගාමී වේ (78% මන්දගාමී වේ). කෙසේ වෙතත්, ෆයර්ෆොක්ස් 51.0.0 (ඇඩෝන ගොඩක් සහිත) ස්විලියම් වේගවත් (වෙනත් ක්‍රෝම් ප්‍රති result ල වලට වඩා ඕප්ස් / තත්පරයෙන් තවමත් මන්දගාමී වේ) මෝටිගේ jQuery g .ග්‍රෙප් (ආර්, ජේක් ෆිල්ටර්) මන්දගාමී (46% මන්දගාමී) වේ. ඔබගේ arr.uniq () 30% මන්දගාමී විය. මම එක් එක් පරීක්ෂණය දෙවරක් ධාවනය කර ස්ථාවර ප්‍රති .ල ලබා ගත්තා. රෆායෙල්ගේ arr.getUnique () බ්‍රව්සර් දෙකෙහිම දෙවන ස්ථානය ලබා ගත්තේය.
ඇඩම් කැට්ස්

jsPerf වේ සපිරි මෙම පරීක්ෂණය කිරීමට මගේ සංස්කරණය සියල්ල සිදු එසේ කළේ නැත, නමුත් එය පරීක්ෂණ දෙකක් එකතු ප්රතිඵලය කළේ, ඒ මොහොතේ දී: Cocco ගේ toUnique () Vamsi ගේ ස්පන්දනය ES6 list.filter () බ්රව්සර යන දෙදෙනා මත ම, පහර swilliams 'sortFilter () FF හි # 1 සඳහා (sortFilter 16% මන්දගාමී විය) සහ ක්‍රෝම් හි # 3 සඳහා ඔබේ වර්ග කළ පරීක්ෂණය (2% කින් මන්දගාමී විය) පරාජය කිරීම.
ඇඩම් කැට්ස්

අහ්, එම පරීක්ෂණ ඉතා කුඩා බව මම දැනගෙන හිටියේ නැහැ. පිළිගත් පිළිතුරට අදහස් දැක්වීමක් එම ගැටළුව විස්තර කරන අතර පරීක්ෂණයට සංශෝධනයක දී නිවැරදි කිරීමක් ඉදිරිපත් කරයි , එහිදී රෆායෙල්ගේ කේතය පහසුවෙන් වේගවත් වන අතර ජොයිට්ජේ 50 හි arr.unique කේතය 98% මන්දගාමී වේ. මෙම විවරණයේ සඳහන් පරිදි මම තවත් සංශෝධනයක් ද කර ඇත්තෙමි .
ඇඩම් කැට්ස්

1
හොඳයි, ඇත්ත වශයෙන්ම ඔබ uniqueශ්‍රිතය තුළ ක්‍රියාත්මක කළ ඇල්ගොරිතම O (n ^ 2) සංකීර්ණතාවයක් ඇති අතර getUniqueO (n) වේ. පළමුවැන්න කුඩා දත්ත කට්ටල මත වේගවත් විය හැකි නමුත් ගණිතය සමඟ ඔබ තර්ක කරන්නේ කෙසේද :) ඔබ එය 1e5 අද්විතීය අයිතම පෙළක් මත ධාවනය කරන්නේ නම් දෙවැන්න වේගවත් බව ඔබට සහතික කළ හැකිය
මිහායිල් ඩුඩින්

32

කාර්ය සාධනය පමණක්! මෙම කේතය මෙහි ඇති සියලුම කේත වලට වඩා 10X වේගවත් වේ * සියලුම බ්‍රව්සර්වල ක්‍රියා කරන අතර අවම මතක බලපෑමක් ඇති කරයි .... සහ තවත්

ඔබට පැරණි අරාව නැවත භාවිතා කිරීමට අවශ්‍ය නොවන්නේ නම්, btw ඔබ එය අද්විතීය බවට පරිවර්තනය කිරීමට පෙර අවශ්‍ය වෙනත් මෙහෙයුම් සිදු කරන්න මෙය බොහෝ විට වේගවත්ම ක්‍රමය වන අතර එය ඉතා කෙටි වේ.

var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];

එවිට ඔබට මෙය උත්සාහ කළ හැකිය

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 1];

function toUnique(a, b, c) { //array,placeholder,placeholder
  b = a.length;
  while (c = --b)
    while (c--) a[b] !== a[c] || a.splice(c, 1);
  return a // not needed ;)
}
console.log(toUnique(array));
//[3, 4, 5, 6, 7, 8, 9, 0, 2, 1]

මම මෙම ලිපිය කියවමින් මෙම ලිපිය කියවමි ...

http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/

මම ලූපයට කැමති නැහැ. එයට බොහෝ පරාමිතීන් ඇත. අප සැවොම කැමති ක්‍රෝම් හැර අනෙක් සියලුම බ්‍රව්සර්වල වේගවත්ම ලූපය වන අතර

කෙසේ වෙතත් මම භාවිතා කරන පළමු ශ්‍රිතය ලිවීය. ඔව් එය ලිපියේ ඇති ශ්‍රිතයට වඩා ටිකක් වේගවත්ය.නමුත් එය ප්‍රමාණවත් නොවේ.unique2()

ඊළඟ පියවර නවීන js භාවිතා කරන්න. Object.keys මම අනෙක් ලූපය js1.7 හි Object.keys සමඟ ආදේශ කළෙමි ... ටිකක් වේගවත් හා කෙටි (ක්‍රෝම් 2x වේගයෙන්);). මදි!. unique3().

මේ අවස්ථාවේදී මම කල්පනා කරමින් සිටියේ මගේ අද්විතීය ක්‍රියාකාරිත්වයේ ඇත්ත වශයෙන්ම මට අවශ්‍ය දේ ගැන ය. මට පැරණි අරාව අවශ්‍ය නැත, මට වේගවත් ශ්‍රිතයක් අවශ්‍යය. ඒ නිසා මම ලූප් + ස්ප්ලයිස් අතර 2 ක් භාවිතා කළෙමි.unique4()

මා පුදුමයට පත් වූ බව කීම නිෂ් less ල ය.

ක්‍රෝම්: සුපුරුදු පරිදි තත්පරයට මෙහෙයුම් 150,000 ක් තත්පරයට මෙහෙයුම් 1800 ක් දක්වා ඉහළ ගියේය.

එනම්: 80,000 op / s එදිරිව 3,500,000 op / s

ios: 18,000 op / s vs 170,000 op / s

සෆාරි: 80,000 op / s vs 6,000,000 op / s

සාධනය http://jsperf.com/wgu හෝ වඩා හොඳින් භාවිතා කරන්න console.time ... මයික්‍රෝ ටයිම් ... ඕනෑම දෙයක්

unique5() ඔබට පරණ අරාව තබා ගැනීමට අවශ්‍ය නම් කුමක් සිදුවේද යන්න පෙන්වීමට පමණි.

ඔබ Array.prototypeකරන්නේ කුමක්දැයි ඔබ නොදන්නේ නම් භාවිතා නොකරන්න . මම පිටපත් හා අතීතය වෙනස් කළා. Object.defineProperty(Array.prototype,...,writable:false,enumerable:false})ඔබට ස්වදේශීය මූලාකෘතියක් සෑදීමට අවශ්‍ය නම් භාවිතා කරන්න. උදාහරණය: https://stackoverflow.com/a/20463021/2450730

ආදර්ශනය http://jsfiddle.net/46S7g/

සටහන: මෙම මෙහෙයුමෙන් පසු ඔබගේ පැරණි අරාව විනාශ වී ඇත / බවට පත්වේ.

ඔබට ඉහත කේතය කියවීමට නොහැකි නම්, ජාවාස්ක්‍රිප්ට් පොතක් කියවන්න හෝ කෙටි කේතය පිළිබඳ පැහැදිලි කිරීම් කිහිපයක් මෙන්න. https://stackoverflow.com/a/21353032/2450730

සමහරු භාවිතා කරති indexOf ... එපා ... http://jsperf.com/dgfgghfghfghghgfhgfhfghfhgfh

හිස් අරා සඳහා

!array.length||toUnique(array); 

4
100.l ර්ල්ස් (නූල්) සමඟ node.js හි පරීක්ෂා කර ඇත. ප්‍රති result ලය underscore.js _.uniq ට වඩා 2x මන්දගාමී විය ... වෙනම jsperf ඔබ සමඟ එකඟ වුවද ( jsperf.com/uniq-performance/5 ), මම කලකිරී සිටිමි :(
xShirase

3
ඔබ jsperf හි නිවැරදිව පරික්‍ෂා නොකරයි ... ඔබේ උදාහරණයේ දී ඔබ සෑම විටම ශ්‍රිතය අර්ථ දක්වයි ... නමුත් underscore.js ශ්‍රිත දැනටමත් අර්ථ දක්වා ඇත .. මෙය මගේ ශ්‍රිතයට ද izes ුවම් කරයි. ! ද පරීක්ෂා 3 සහ 4. දෙයක් තවත් දෙයක් මම කියන්න ඕනේ ඔබ මිශ්ර විචල්යයන් (නූල් සහ අංක) භාවිතා කරන්නේ නම් ඔබ [ආ] වෙනුවට යුතු බවයි == සහ [ඇ] සහ [ආ] සමඟ = කරුණාකර [ඇ]
cocco

2
JsPerf නිවැරදි දැයි මට විශ්වාස නැත, නමුත් අඩු කිරීමේ විකල්පය (මට තේරුම් ගැනීමට පහසුය) ඔබේ විසඳුමට වඩා තරමක් 94% වේගවත් බව පෙනේ. jsperf.com/reduce-for-distinct සංස්කරණය කරන්න: ඔබගේ ක්‍රෝම් මත මන්දගාමී වේ, එජ් මතද එය ෆයර්ෆොක්ස් මත වේගවත් වේ.
වික්ටර් අයිවන්ස්

3
කුඩා අරා / අඩු අනුපිටපත් ප්‍රතිශතයකින් පමණක් භාවිතා කළ හැකිය. අද්විතීය නොවන වස්තුවක් හමු වූ සෑම අවස්ථාවකම, එන්ජිමට ඉතිරි සියලුම අංග වමට මාරුවීමට බල කෙරෙනු ඇත , පහත පරිදි: 1) ඒවා හරහා නැවත ක්‍රියා කිරීම 2) ඒවා කියවීම 3) ඒවා නව ස්ථානයකට ලියන්න. පසුව, එය එක් spliced අංගයක් සමග නව අරාව, සහ එහි ප්රතිඵලයක් ලෙස ප්රතිලාභ එය නිර්මාණය ... ඇල්ගොරිතමය ඉක්මනින් විශාල පෙලගැස්මක් / නිතර නිතර අනුපිටපත් සමග හායනය. 1000-> 10000-> 50000 සහ ~ 40% අනුපිටපත් සඳහා, සාමාන්‍යයෙන් ගතවන කාලය 2-> 775-> 19113 ms වැනි වේ. (ප්‍රමාණය 1-> x10-> x5 ලෙස වෙනස් වේ, කාලය 1-> x10-> x25 ලෙස වෙනස් වේ) Chrome හි.
ankhzet

1
ස්තූතියි. හොඳ ප්රවේශයක්. නමුත් නිවැරදි අයිතම ඇණවුම ගැන කුමක් කිව හැකිද?
ලිබර්බර්න්

29

මෙහි බොහෝ පිළිතුරු ආරම්භකයින්ට ප්‍රයෝජනවත් නොවනු ඇත. අරාව අක්‍රීය කිරීම දුෂ්කර නම්, ඔවුන් සැබවින්ම මූලාකෘති දාමය ගැන හෝ jQuery ගැන දැනගනීවිද?

නවීන බ්රවුසර, පිරිසිදු කිරීම හා සරල විසඳුමක් දී දත්ත ගබඩා කිරීම සඳහා වන Set අද්විතීය වටිනාකම් ලැයිස්තුවක් විය කිරීමට සැලසුම් කර ඇත අතර,.

const cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
const uniqueCars = Array.from(new Set(cars));

මෙම Array.fromඔබ පෙලගැස්මක් ඇති බව නියමයි ක්රම (ලක්ෂණ) සියලු ලබාගැනීම පහසු බව එසේ රැසක් සඳහා නැවත Set බවට පරිවර්තනය කිරීමට ප්රයෝජනවත් වේ. එකම දේ කිරීමට වෙනත් ක්‍රමතිබේ . ForEachArray.from වැනි ප්‍රයෝජනවත් විශේෂාංග කට්ටලවල ඇති බැවින් ඔබට කිසිසේත් අවශ්‍ය නොවනු ඇත.

ඔබට පැරණි ඉන්ටර්නෙට් එක්ස්ප්ලෝරර් සඳහා සහය දැක්වීමට අවශ්‍ය නම්, ඒ අනුව සෙට් භාවිතා කළ නොහැකි නම්, සරල ක්‍රමයක් නම්, නව අරා වෙත අයිතම පිටපත් කිරීම, ඒවා දැනටමත් නව අරාවෙහි තිබේදැයි පරීක්ෂා කර බැලීමයි.

// Create a list of cars, with duplicates.
var cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
// Create a list of unique cars, to put a car in if we haven't already.
var uniqueCars = [];

// Go through each car, one at a time.
cars.forEach(function (car) {
    // The code within the following block runs only if the
    // current car does NOT exist in the uniqueCars list
    // - a.k.a. prevent duplicates
    if (uniqueCars.indexOf(car) === -1) {
        // Since we now know we haven't seen this car before,
        // copy it to the end of the uniqueCars list.
        uniqueCars.push(car);
    }
});

මෙය ක්ෂණිකව නැවත භාවිතා කිරීමට, අපි එය ශ්‍රිතයකට දමමු.

function deduplicate(data) {
    if (data.length > 0) {
        var result = [];

        data.forEach(function (elem) {
            if (result.indexOf(elem) === -1) {
                result.push(elem);
            }
        });

        return result;
    }
}

එබැවින් අනුපිටපත් ඉවත් කිරීම සඳහා, අපි දැන් මෙය කරන්නෙමු.

var uniqueCars = deduplicate(cars);

මෙම deduplicate(cars)කොටස බවට පත් අප නම් කරන ලද දෙයක් නිසා විට කාර්යය සම්පූර්ණ වෙනවා.

ඔබ කැමති ඕනෑම අරාවක නම එය සම්මත කරන්න.


මාර්ගය වන විට, මගේ තාක්‍ෂණය නම්‍යශීලී බව පෙන්වීමට මම නූල්වලින් පිරුණු පෙළක් භාවිතා කළෙමි. එය සංඛ්‍යා සඳහා නිසි ලෙස ක්‍රියා කරයි.
සෙත් හොලඩේ

21
["Defects", "Total", "Days", "City", "Defects"].reduce(function(prev, cur) {
  return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev;
 }, []);

[0,1,2,0,3,2,1,5].reduce(function(prev, cur) {
  return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev;
 }, []);

ඔබ හුදෙක් pushමූලද්‍රව්‍යය අරාව මතට නොගන්නේ මන්දැයි ඔබට පැහැදිලි කළ හැකිද concat? මම තල්ලු භාවිතා කිරීමට උත්සාහ කළ අතර එය අසාර්ථක විය. මම පැහැදිලි කිරීමක් සොයමි.
makenova

1
හේතුව ප්‍රතිලාභ වටිනාකමයි. කොන්කට් විසින් නවීකරණය කරන ලද අරාව නැවත ලබා දෙයි (අඩු කිරීමේ ශ්‍රිතය තුළ ආපසු ලබා දිය යුතු දේ හරියටම), තල්ලු මඟින් ඔබට තල්ලු කළ අගයට ප්‍රවේශ විය හැකි දර්ශකයක් ලබා දෙයි. එය ඔබේ ප්‍රශ්නයට පිළිතුරු දෙයිද?
sergeyz

පෙනෙන විදිහට, මෙම විසඳුම ක්‍රෝම් (සහ නෝඩ්) වල තරමක් වේගවත් ය. jsperf.com/reduce-for-distinct එය ES6 අනුවාදයයි: [0,1,2,0,3,2,1,5].reduce((prev, cur) => ~prev.indexOf(cur) ? prev : prev.concat([cur]), []);
වික්ටර් අයිවන්ස්

පැති සටහන: මෙම ක්‍රියාත්මක කිරීම NaNමිත්‍රශීලී නොවේ
Alireza

21

අපට මෙය ES6 කට්ටල භාවිතයෙන් කළ හැකිය:

var duplicatedArray = [1, 2, 3, 4, 5, 1, 1, 1, 2, 3, 4];
var uniqueArray = Array.from(new Set(duplicatedArray));

console.log(uniqueArray);

// ප්‍රතිදානය වනු ඇත

uniqueArray = [1,2,3,4,5];

18

මෙම මූලාකෘති getUniquei වැනි Array තිබේ නම් නිසා නොවේ, සම්පූර්ණයෙන්ම නිවැරදි ය: ["1",1,2,3,4,1,"foo"]එය ආපසු ඇත ["1","2","3","4"]හා "1"සංගීත හා 1එය පූර්ණ සංඛ්යාමය ය; ඒවා වෙනස් ය.

මෙන්න නිවැරදි විසඳුමක්:

Array.prototype.unique = function(a){
    return function(){ return this.filter(a) }
}(function(a,b,c){ return c.indexOf(a,b+1) < 0 });

භාවිතා කරමින්:

var foo;
foo = ["1",1,2,3,4,1,"foo"];
foo.unique();

ඉහත සඳහන් දෑ නිපදවනු ["1",2,3,4,1,"foo"]ඇත.


2
$foo = 'bar'විචල්යයන් ප්රකාශ කිරීමේ PHP ක්රමය එය බව සලකන්න . එය ජාවාස්ක්‍රිප්ට් තුළ ක්‍රියා කරනු ඇත, නමුත් ව්‍යංග ගෝලීය නිර්මාණය කරනු ඇත, සාමාන්‍යයෙන් එය නොකළ යුතුය.
කැමිලෝ මාටින්

Am කැමිලෝ මාටින්ට කණගාටුයි නමුත් ඔබ වැරදියි, oo foo ගෝලීය වන්නේ උදාහරණය වසා දැමීමක් නොමැති නිසා ඔහුට var keyword නැති වී ඇති බැවිනි. ඩොලරයට කිසිම සම්බන්ධයක් නැත jsfiddle.net/robaldred/L2MRb
රොබ්

9
Ob රොබ් යනු හරියටම මම කියන්නේ, $fooජාවාස්ක්‍රිප්ට් හි විචල්‍යයන් ප්‍රකාශ කිරීමේ ක්‍රමය PHP පුද්ගලයින් සිතනු ඇත var foo.
කැමිලෝ මාටින්

15

Array.prototype දිගු නොකර (එය නරක පුරුද්දක් යැයි කියනු ලැබේ) හෝ jquery / underscore භාවිතා නොකර, ඔබට සරලවම filterඅරාව කළ හැකිය .

අවසාන සිදුවීම තබා ගැනීමෙන්:

    function arrayLastUnique(array) {
        return array.filter(function (a, b, c) {
            // keeps last occurrence
            return c.indexOf(a, b + 1) < 0;
        });
    },

හෝ පළමු සිදුවීම:

    function arrayFirstUnique(array) {
        return array.filter(function (a, b, c) {
            // keeps first occurrence
            return c.indexOf(a) === b;
        });
    },

හොඳයි, එය ජාවාස්ක්‍රිප්ට් ECMAScript 5+ පමණක් වන අතර එයින් අදහස් කරන්නේ IE9 + පමණි, නමුත් ස්වදේශීය HTML / JS (වින්ඩෝස් ස්ටෝර් ඇප්, ෆයර්ෆොක්ස් ඕඑස්, සෙන්චා, ෆොනෙගෑප්, ටයිටේනියම්, ...) හි වර්ධනයක් සඳහා එය කදිමයි.


2
එය js 1.6 යන කාරණයෙන් ඔබට භාවිතා කළ නොහැකි බවක් අදහස් නොවේ filter. දී MDN පිටුව ඔවුන් Internet Explorer සඳහා ක්රියාත්මක කර, මම අදහස් කලේ, පැරණි බ්රව්සර. එසේම: JS 1.6 යන්නෙන් අදහස් කරන්නේ ෆයර්ෆොක්ස් හි js එන්ජිම පමණි, නමුත් නිවැරදිව කිවහොත් එය ECMAScript 5 බව පැවසිය හැකිය.
කැමිලෝ මාටින්

Am කැමිලෝ මාටින් I 1.6 ECMAScript5 ලෙස වෙනස් කළේය. ස්තූතියි.
කෝර්

15
[...new Set(duplicates)]

මෙය සරලම එකක් වන අතර එම්ඩීඑන් වෙබ් ලියකියවිලි වලින් යොමු කෙරේ .

const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
console.log([...new Set(numbers)]) // [2, 3, 4, 5, 6, 7, 32]

මෙම කේතය මඟින් ගැටළුව විසඳන්නේ කෙසේද සහ ඇයි යන්න පිළිබඳ පැහැදිලි කිරීමක් ඇතුළුව ප්‍රශ්නය විසඳිය හැකි අතර එය ඔබගේ තනතුරේ ගුණාත්මකභාවය වැඩි දියුණු කිරීමට සැබවින්ම උපකාරී වන අතර බොහෝ විට වැඩි ඡන්ද ප්‍රමාණයක් ලැබෙනු ඇත. ඔබ දැන් අසන පුද්ගලයා පමණක් නොව අනාගතයේ දී පා readers කයන් සඳහා වන ප්‍රශ්නයට පිළිතුරු සපයන බව මතක තබා ගන්න. පැහැදිලි කිරීමක් එක් කිරීමට කරුණාකර ඔබේ පිළිතුර සංස්කරණය කරන්න, සහ සීමාවන් සහ උපකල්පන අදාළ වන්නේ කුමක් දැයි ඇඟවීමක් කරන්න.
id.ot

14

මැජික්

a.filter(e=>!(t[e]=e in t)) 

O (n) කාර්ය සාධනය ; අපි හිතන්නේ ඔබේ අරාව ක්‍රියාත්මකයි aසහ t={}. මෙහි පැහැදිලි කිරීම (+ ජෙප් impr.)


14
මෙම පෙනුම ඉතා සිසිල් ය, පැහැදිලි පැහැදිලි කිරීමකින් තොරව මම වැටුණෙමි, මම මෙය ක්‍රියාත්මක කරන විට ඔබ මගේ
බිට්කොයින් ලබා ගනීවි

3
මා අදහස් කළේ ඔබ යම් පැහැදිලි කිරීමක් සමඟ ඔබේ පිළිතුර පුළුල් කළ යුතු අතර එය ප්‍රතිනිර්මාණය කිරීම පිළිබඳව අදහස් දැක්වීමයි. මිනිසුන්ට මේ වගේ ප්‍රයෝජනවත් පිළිතුරු ලැබේ යැයි බලාපොරොත්තු නොවන්න. (එය ඇත්තෙන්ම සිසිල් බව පෙනෙන්නට තිබුණත් බොහෝ විට එය ක්‍රියාත්මක වේ)
ඔන්ඩෙජ් එලෙස්කෝ

1
@Jeppe මම ඔබේ වැඩි දියුණු කිරීම ක්රියාත්මක විට මම අත් හහා ක්රියාත්මක (මම භාවිතා කල හැකි බව දන්නේ නැහැ පෙර inවඩා වෙනත් ඉදිකිරීම් පිටත ක්රියාකරු forපුඩුවක්: පී) - ස්තූතියි - මම එය අගය සහ ඔබගේ අනෙකුත් හොඳ පිළිතුරු +2 ලබා දෙනු ඇත .
Kamil Kiełczewski

2
එය tපෙරීමෙන් පසු ජීවමාන වන ගෝලීය විචල්‍යයක් නිර්මාණය කරන්නේ නැද්ද … ??
පිලිප්

1
මෙය සැබවින්ම උපක්‍රමශීලී විසඳුමකි. අවාසනාවකට මෙන්, ඔබට ගෝලීය විචල්‍යයක් නිර්වචනය කිරීමට සහ / හෝ ගෝලීය සැඟවීමට ඔබේ මොඩියුල බණ්ඩලය මත විශ්වාසය තැබීමට අවශ්‍ය නම් මිස ප්‍රකාශනයෙන් පිටත ප්‍රකාශ කළ යුතුය. එය මනස්කාන්ත බවක් පෙනේ, නමුත් ඔබටම (සහ ඔබේ dev කණ්ඩායමට) උදව්වක් කර ලයිනර් දෙකක් ලියන්න: t = {let ඉඩ දෙන්න; a.filter (e =>! (t [e] = e in t))
ford04

13

ඔබ මූලාකෘති රාමුවක් භාවිතා කරන්නේ නම්, 'සඳහා' ලූප අවශ්‍ය නොවේ, ඔබට http://www.prototypejs.org/api/array/uniq භාවිතා කළ හැකිය :

var a = Array.uniq();  

එමඟින් අනුපිටපත් නොමැති අනුපිටපත් පෙළක් නිපදවනු ඇත. ඔබේ ප්‍රශ්නය මට හමු වූයේ වෙනස් අරා වාර්තා ගණනය කිරීමේ ක්‍රමයක් සෙවීමෙනි

uniq ()

මම පාවිච්චි කළා

ප්‍රමාණය ()

මගේ සරල ප්‍රති .ලය ලැබුණා. ps මම යමක් වැරදියට ටයිප් කළා නම් කණගාටුයි

සංස්කරණය කරන්න: ඔබට නිර්වචනය නොකළ වාර්තා වලින් ගැලවීමට අවශ්‍ය නම් ඔබට එකතු කිරීමට අවශ්‍ය විය හැකිය

සංගත()

පෙර, මේ වගේ:

var a = Array.compact().uniq();  

14
මට වඩා හොඳ පිළිතුරක් හමු වූ නිසා, මාතෘකා ගැන ඇසූ තැනැත්තාට පමණක් නොව සියලු දෙනාටම යැයි මම සිතමි
Decbel

12

එයට හේතුව 0ජාවාස්ක්‍රිප්ට් හි ව්‍යාජ අගයකි.

this[i] අරාවෙහි අගය 0 හෝ වෙනත් ව්‍යාජ අගයක් නම් ව්‍යාජ වනු ඇත.


අහ්හ්, හරි, මම දැන් දකිමි ... නමුත් එය ක්‍රියාත්මක කිරීමට පහසු විසඳුමක් තිබේද?
Mottie

12

දැන් කට්ටල භාවිතා කිරීමෙන් ඔබට අනුපිටපත් ඉවත් කර නැවත අරාව බවට පරිවර්තනය කළ හැකිය.

var names = ["Mike","Matt","Nancy", "Matt","Adam","Jenny","Nancy","Carl"];

console.log([...new Set(names)])

තවත් විසඳුමක් වන්නේ වර්ග කිරීම සහ පෙරණය භාවිතා කිරීමයි

var names = ["Mike","Matt","Nancy", "Matt","Adam","Jenny","Nancy","Carl"];
var namesSorted = names.sort();
const result = namesSorted.filter((e, i) => namesSorted[i] != namesSorted[i+1]);
console.log(result);


11
Array.prototype.getUnique = function() {
    var o = {}, a = []
    for (var i = 0; i < this.length; i++) o[this[i]] = 1
    for (var e in o) a.push(e)
    return a
}

අරාවෙහි වස්තූන් / අරා අඩංගු නම් මෙය ක්‍රියා නොකරනු ඇතැයි මම සිතමි, තවද එය පරිමාණයන් ආරක්ෂා කරයිදැයි මට විශ්වාස නැත.
කැමිලෝ මාටින්

ඔව්, සෑම දෙයක්ම දැඩි වේ. සමානාත්මතාවය සැසඳීම තවමත් දැඩි ලෙස පැවතියද, මුල් අගය oනිකම්ම වෙනුවට ගබඩා කිරීමෙන් එය නිවැරදි කළ 1හැකිය (හැකි සෑම ජාවාස්ක්‍රිප්ට් සමානතාවයකින්ම එය අසාධාරණ යැයි නොපෙනේ).
ephemient

Array.prototype දිගු කළ හැක්කේ ගණන් කළ නොහැකි ක්‍රම වලින් පමණි .... Object.defineProperty (Array.prototype, "getUnique", {}) ... නමුත් උපකාරක වස්තුවක් භාවිතා කිරීමේ අදහස ඉතා හොඳයි
bortunac

11

මට තරමක් වෙනස් ගැටළුවක් ඇති අතර එහිදී අනුපිටපත් හැඳුනුම් ගුණාංග සහිත වස්තු අරාවකින් ඉවත් කිරීමට අවශ්‍ය විය. මෙය ක්‍රියාත්මක විය.

let objArr = [{
  id: '123'
}, {
  id: '123'
}, {
  id: '456'
}];

objArr = objArr.reduce((acc, cur) => [
  ...acc.filter((obj) => obj.id !== cur.id), cur
], []);

console.log(objArr);


10

සරලම පිළිතුර නම්:

const array = [1, 1, 2, 2, 3, 5, 5, 2];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // [1, 2, 3, 5]

සරල නමුත් එය වස්තු සමූහයක් සමඟ ක්‍රියා නොකරයි.
තන්වා ච.

8

සිට Shamasis භට්ටාචාර්යා ගේ බ්ලොග් (සාමාන්ය (2n) කාලය සංකීර්ණත්වය):

Array.prototype.unique = function() {
    var o = {}, i, l = this.length, r = [];
    for(i=0; i<l;i+=1) o[this[i]] = this[i];
    for(i in o) r.push(o[i]);
    return r;
};

සිට පෝල් අයර්ලන්ත ගේ බ්ලොග් : jQuery මත වැඩි දියුණු කිරීම .unique():

(function($){

    var _old = $.unique;

    $.unique = function(arr){

        // do the default behavior only if we got an array of elements
        if (!!arr[0].nodeType){
            return _old.apply(this,arguments);
        } else {
            // reduce the array to contain no dupes via grep/inArray
            return $.grep(arr,function(v,k){
                return $.inArray(v,arr) === k;
            });
        }
    };
})(jQuery);

// in use..
var arr = ['first',7,true,2,7,true,'last','last'];
$.unique(arr); // ["first", 7, true, 2, "last"]

var arr = [1,2,3,4,5,4,3,2,1];
$.unique(arr); // [1, 2, 3, 4, 5]

8

ගේබ්‍රියෙල් සිල්වෙයිරා එම කාර්යය එසේ ලිව්වේ ඇයිදැයි මට විශ්වාස නැත, නමුත් සරල ආකාරයකින් මා වෙනුවෙන් මෙන්ම අවම කිරීමකින් තොරව ක්‍රියා කරයි:

Array.prototype.unique = function() {
  return this.filter(function(value, index, array) {
    return array.indexOf(value, index + 1) < 0;
  });
};

හෝ කෝපි ස්ක්‍රිප්ට් හි:

Array.prototype.unique = ->
  this.filter( (value, index, array) ->
    array.indexOf(value, index + 1) < 0
  )

8

අමතර පරායත්තතාවයන් සමඟ ඔබ හොඳින් සිටී නම්, හෝ ඔබට දැනටමත් ඔබේ කේත පදනමේ පුස්තකාලයක් තිබේ නම්, ඔබට LoDash (හෝ අන්ඩර්ස්කෝර්) භාවිතා කර ස්ථානයක ඇති අනුපිටපත් ඉවත් කළ හැකිය.

භාවිතය

ඔබගේ කේත රචනයේ දැනටමත් එය නොමැති නම්, එය npm භාවිතයෙන් ස්ථාපනය කරන්න:

npm install lodash

ඉන්පසු එය පහත පරිදි භාවිතා කරන්න:

import _ from 'lodash';
let idArray = _.uniq ([
    1,
    2,
    3,
    3,
    3
]);
console.dir(idArray);

පිටතට:

[ 1, 2, 3 ]

8

මෙයට බොහෝ පිළිතුරු ලැබී ඇත, නමුත් එය මගේ විශේෂ අවශ්‍යතාව සපුරාලුවේ නැත.

බොහෝ පිළිතුරු මේ වගේ ය:

a.filter((item, pos, self) => self.indexOf(item) === pos);

නමුත් මෙය සංකීර්ණ වස්තූන්ගේ අරා සඳහා ක්‍රියා නොකරයි.

අපට මේ වගේ පෙළක් ඇති බව පවසන්න:

const a = [
 { age: 4, name: 'fluffy' },
 { age: 5, name: 'spot' },
 { age: 2, name: 'fluffy' },
 { age: 3, name: 'toby' },
];

අද්විතීය නම් සහිත වස්තූන් අපට අවශ්‍ය නම්, array.prototype.findIndexඒ වෙනුවට අප භාවිතා කළ යුත්තේ array.prototype.indexOf:

a.filter((item, pos, self) => self.findIndex(v => v.name === item.name) === pos);

විශිෂ්ට විසඳුමක්, ශ්‍රිතයකින් නව අරාවක් නැවත පැමිණෙන බවට පරිස්සම් වන්න. (එය වෙනස් නොවේ)
තන්වා ච.

7

සරල ක්‍රමයකින් අද්විතීය අරාව අගයන් සොයා ගැනීම

function arrUnique(a){
  var t = [];
  for(var x = 0; x < a.length; x++){
    if(t.indexOf(a[x]) == -1)t.push(a[x]);
  }
  return t;
}
arrUnique([1,4,2,7,1,5,9,2,4,7,2]) // [1, 4, 2, 7, 5, 9]

7

වසර කිහිපයක් තිස්සේ පිළිගත් පිළිතුර ලෙස සැලකෙන රෆායෙල්ගේ පිළිතුර අපට අහිමි වී ඇති බව පෙනේ . ඔබට (අවම වශයෙන් 2017 දී) ඔබට මිශ්‍ර ආකාරයේ අරාවක් නොමැති නම් හොඳම ක්‍රියාකාරී විසඳුම මෙයයි :

Array.prototype.getUnique = function(){
    var u = {}, a = [];
    for (var i = 0, l = this.length; i < l; ++i) {
        if (u.hasOwnProperty(this[i])) {
            continue;
        }
        a.push(this[i]);
        u[this[i]] = 1;
    }
return a;
}

ඔබ නම් කළ මිශ්ර-වර්ගය මාලාවක් ඇති, ඔබ එහි පූරක ප්රධාන serialize හැක:

Array.prototype.getUnique = function() {
    var hash = {}, result = [], key; 
    for ( var i = 0, l = this.length; i < l; ++i ) {
        key = JSON.stringify(this[i]);
        if ( !hash.hasOwnProperty(key) ) {
            hash[key] = true;
            result.push(this[i]);
        }
    }
    return result;
}

6

අමුතු දෙයක් මෙය මීට පෙර යෝජනා කර නැත .. idඅරාව තුළ වස්තු යතුරෙන් ( පහළ) අනුපිටපත් ඉවත් කිරීමට ඔබට මෙවැනි දෙයක් කළ හැකිය:

const uniqArray = array.filter((obj, idx, arr) => (
  arr.findIndex((o) => o.id === obj.id) === idx
)) 

දෙකම filter()සහ findIndex()අරාව හරහා නැවත යෙදිය යුතු නොවේද? එමඟින් මෙය ද්විත්ව ලූපයක් වන අතර එම නිසා මෙහි ඇති වෙනත් පිළිතුරකට වඩා දෙගුණයක් මිල අධික වේ.
ඇඩම් කැට්ස්

D ඇඩම්කාට්ස් ඔව් එය n + 1 වතාවක් අරාව හරහා නැවත ක්‍රියා කරයි. සිතියම, පෙරණය, දර්ශක ඕෆ්, අඩු කිරීම යනාදිය භාවිතා කරමින් මෙහි ඇති අනෙක් පිළිතුරු ද මෙය කළ යුතු බව කරුණාවෙන් සලකන්න. වළක්වා ගැනීම සඳහා, ඔබට new Set()ග්‍රෝස්ගේ පිළිතුරට සමාන බැලීමේ වස්තුවක් භාවිතා කළ හැකිය.
daviestar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.