Jak scalić dwie tablice w JavaScript i de-duplicate items
Mam dwie tablice JavaScript:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
Chcę, aby wyjście było:
var array3 = ["Vijendra","Singh","Shakya"];
Tablica wyjściowa powinna mieć usunięte powtarzające się słowa.
Jak połączyć dwie tablice w JavaScript, aby uzyskać tylko unikalne elementy z każdej tablicy w tej samej kolejności, w jakiej zostały wstawione do oryginalnych tablic?
30 answers
Aby po prostu połączyć tablice (bez usuwania duplikatów)
Użycie wersji ES5 Array.concat
:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = array1.concat(array2); // Merges both arrays
// [ 'Vijendra', 'Singh', 'Singh', 'Shakya' ]
Użycie wersji ES6 destrukcja
const array1 = ["Vijendra","Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = [...array1, ...array2];
Ponieważ nie ma "wbudowanego" sposobu usuwania duplikatów (ECMA-262 faktycznie ma {[7] } co byłoby do tego świetne), musimy to zrobić ręcznie:
Array.prototype.unique = function() {
var a = this.concat();
for(var i=0; i<a.length; ++i) {
for(var j=i+1; j<a.length; ++j) {
if(a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
};
Następnie, aby go użyć:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
// Merges both arrays and gets unique items
var array3 = array1.concat(array2).unique();
To również zachowa kolejność tablic(tzn. nie wymaga sortowania).
Ponieważ wielu ludzi zirytowane są prototypowe Rozszerzanie pętli Array.prototype
i for in
, Oto mniej inwazyjny sposób jej użycia:
function arrayUnique(array) {
var a = array.concat();
for(var i=0; i<a.length; ++i) {
for(var j=i+1; j<a.length; ++j) {
if(a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
}
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
// Merges both arrays and gets unique items
var array3 = arrayUnique(array1.concat(array2));
Dla tych, którzy mają szczęście pracować z przeglądarkami, w których ES5 jest dostępny, możesz użyć Object.defineProperty
w następujący sposób:
Object.defineProperty(Array.prototype, 'unique', {
enumerable: false,
configurable: false,
writable: false,
value: function() {
var a = this.concat();
for(var i=0; i<a.length; ++i) {
for(var j=i+1; j<a.length; ++j) {
if(a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 16:45:30
Z Podkreśleniem.js lub Lo-Dash można zrobić:
_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:32:13
Najpierw połącz dwie tablice, następnie odfiltruj tylko unikalne elementy.
var a = [1, 2, 3], b = [101, 2, 1, 10];
var c = a.concat(b);
var d = c.filter(function (item, pos) {return c.indexOf(item) == pos});
// d is [1,2,3,101,10]
Http://jsfiddle.net/simo/98622/
Edit
Zgodnie z sugestią @Dmitry (zobacz drugi komentarz poniżej) bardziej wydajnym rozwiązaniem byłoby odfiltrowanie unikalnych elementów w b
przed połączeniem z a
var a = [1, 2, 3], b = [101, 2, 1, 10];
var c = a.concat(b.filter(function (item) {
return a.indexOf(item) < 0;
}));
// d is [1,2,3,101,10]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-02 22:25:45
Jest to rozwiązanie ECMAScript 6 wykorzystujące operator spreadu i array generics.
Obecnie działa tylko z Firefoksem i ewentualnie Internet Explorer Technical Preview.
Ale jeśli użyjesz Babel , możesz go mieć teraz.
// Input: [ [1, 2, 3], [101, 2, 1, 10], [2, 1] ]
// Output: [1, 2, 3, 101, 10]
function mergeDedupe(arr)
{
return [...new Set([].concat(...arr))];
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:39:25
ES6
array1.push(...array2) // => don't remove duplication
Lub
[...array1,...array2] // => don't remove duplication
Lub
[...new Set([...array1 ,...array2])]; // => remove duplication
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-17 03:21:51
Oto nieco inne spojrzenie na pętlę. Dzięki niektórym optymalizacjom w najnowszej wersji Chrome jest to najszybsza metoda rozwiązywania połączenia dwóch tablic (Chrome 38.0.2111).
Http://jsperf.com/merge-two-arrays-keeping-only-unique-values
var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [];
var arr = array1.concat(array2),
len = arr.length;
while (len--) {
var itm = arr[len];
if (array3.indexOf(itm) === -1) {
array3.unshift(itm);
}
}
While loop: ~ 589k / s
filtr: ~445km / s
lodash: 308k ops / s
dla pętli: 225k/s
Komentarz wskazywał, że jedna z moich zmiennych konfiguracyjnych powodowała, że moja pętla przeciągnij przed resztą, ponieważ nie musiał inicjalizować pustej tablicy do zapisu. Zgadzam się z tym, więc przepisałem test na równi z polem gry i włączyłem jeszcze szybszą opcję.
Http://jsperf.com/merge-two-arrays-keeping-only-unique-values/21
var whileLoopAlt = function(array1, array2) {
var array3 = [];
var arr = array1.concat(array2);
var len = arr.length;
var assoc = {};
while(len--) {
var itm = arr[len];
if(!assoc[itm]) { // Eliminate the indexOf call
array3.unshift(itm);
assoc[itm] = true;
}
}
return array3;
};
W tym alternatywnym rozwiązaniu połączyłem asocjacyjne rozwiązanie tablicy jednej odpowiedzi, aby wyeliminować wywołanie .indexOf()
W pętli, które spowalniało wiele rzeczy za pomocą drugiej pętli, i włączyłem kilka innych optymalizacji, które inni użytkownicy zasugerowali również w swoich odpowiedziach.
Górna odpowiedź z podwójną pętlą na każdej wartości (i-1) jest nadal znacznie wolniejsza. lodash wciąż robi silne wrażenie i nadal polecam go każdemu, kto nie ma nic przeciwko dodaniu biblioteki do swojego projektu. Dla tych, którzy nie chcą, moja pętla while jest nadal dobrą odpowiedzią, a odpowiedź filtra ma bardzo silny pokaz tutaj, pokonując wszystkie moje testy z najnowszym Canary Chrome (44.0.2360)
Sprawdź odpowiedź Mike ' a i Dana Stockera, jeśli chcesz przyspieszyć. Są to zdecydowanie najszybsze ze wszystkich wyników po przejściu przez prawie wszystkie realne odpowiedzi.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:36:46
Używając Zestawu (ECMAScript 2015), będzie to tak proste:
const array1 = ["Vijendra", "Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = Array.from(new Set(array1.concat(array2)));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-06 19:05:58
Możesz to zrobić po prostu za pomocą ECMAScript 6,
var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [...new Set([...array1 ,...array2])];
console.log(array3); // ["Vijendra", "Singh", "Shakya"];
- Użyj operatora spreadu do łączenia tablicy.
- użyj zestawu do utworzenia odrębnego zestawu elementów.
- ponownie użyj operatora spread, aby przekonwertować Zbiór na tablicę.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:50:33
Array.prototype.merge = function(/* variable number of arrays */){
for(var i = 0; i < arguments.length; i++){
var array = arguments[i];
for(var j = 0; j < array.length; j++){
if(this.indexOf(array[j]) === -1) {
this.push(array[j]);
}
}
}
return this;
};
Znacznie lepszą funkcję scalania tablic.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-22 18:44:21
Dorzucę tylko dwa centy.
function mergeStringArrays(a, b){
var hash = {};
var ret = [];
for(var i=0; i < a.length; i++){
var e = a[i];
if (!hash[e]){
hash[e] = true;
ret.push(e);
}
}
for(var i=0; i < b.length; i++){
var e = b[i];
if (!hash[e]){
hash[e] = true;
ret.push(e);
}
}
return ret;
}
Jest to metoda, której często używam, używa obiektu jako tabeli hashlookup do sprawdzania duplikatów. Zakładając, że hash jest O (1), to działa w O (N), gdzie n jest a. length + b. length. Szczerze mówiąc, nie mam pojęcia, jak przeglądarka robi hash, ale działa dobrze na wielu tysiącach punktów danych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-12 19:50:20
Dlaczego nie używasz obiektu? Wygląda na to, że próbujesz wymodelować zestaw. To jednak nie zachowa porządku.
var set1 = {"Vijendra":true, "Singh":true}
var set2 = {"Singh":true, "Shakya":true}
// Merge second object into first
function merge(set1, set2){
for (var key in set2){
if (set2.hasOwnProperty(key))
set1[key] = set2[key]
}
return set1
}
merge(set1, set2)
// Create set from array
function setify(array){
var result = {}
for (var item in array){
if (array.hasOwnProperty(item))
result[array[item]] = true
}
return result
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:30:39
Unikaj zagnieżdżonych pętli(O (N^2)) i .indexOf()
(+O (n)).
function merge(a, b) {
var hash = {}, i;
for (i=0; i<a.length; i++) {
hash[a[i]]=true;
}
for (i=0; i<b.length; i++) {
hash[b[i]]=true;
}
return Object.keys(hash);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-20 14:55:47
Mój półtora grosza:
Array.prototype.concat_n_dedupe = function(other_array) {
return this
.concat(other_array) // add second
.reduce(function(uniques, item) { // dedupe all
if (uniques.indexOf(item) == -1) {
uniques.push(item);
}
return uniques;
}, []);
};
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var result = array1.concat_n_dedupe(array2);
console.log(result);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-20 22:29:23
Uprościłem odpowiedź simo i przekształciłem ją w ładną funkcję.
function mergeUnique(arr1, arr2){
return arr1.concat(arr2.filter(function (item) {
return arr1.indexOf(item) === -1;
}));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-09 12:30:27
Najlepsze rozwiązanie...
Możesz sprawdzić bezpośrednio w konsoli przeglądarki, naciskając...
Bez duplikatu
a = [1, 2, 3];
b = [3, 2, 1, "prince"];
a.concat(b.filter(function(el) {
return a.indexOf(el) === -1;
}));
Z duplikatem
["prince", "asish", 5].concat(["ravi", 4])
Jeśli chcesz bez duplikatu możesz spróbować lepszego rozwiązania stąd - krzycząc kod.
[1, 2, 3].concat([3, 2, 1, "prince"].filter(function(el) {
return [1, 2, 3].indexOf(el) === -1;
}));
Spróbuj na konsoli przeglądarki Chrome
f12 > console
Wyjście:
["prince", "asish", 5, "ravi", 4]
[1, 2, 3, "prince"]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:49:08
//Array.indexOf was introduced in javascript 1.6 (ECMA-262)
//We need to implement it explicitly for other browsers,
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt, from)
{
var len = this.length >>> 0;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
//now, on to the problem
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var merged = array1.concat(array2);
var t;
for(i = 0; i < merged.length; i++)
if((t = merged.indexOf(i + 1, merged[i])) != -1)
{
merged.splice(t, 1);
i--;//in case of multiple occurrences
}
Implementacja metody indexOf
dla innych przeglądarek pochodzi z MDC
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-18 10:56:09
Można to zrobić za pomocą Set.
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = array1.concat(array2);
var tempSet = new Set(array3);
array3 = Array.from(tempSet);
//show output
document.body.querySelector("div").innerHTML = JSON.stringify(array3);
<div style="width:100%;height:4rem;line-height:4rem;background-color:steelblue;color:#DDD;text-align:center;font-family:Calibri" >
temp text
</div>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 10:02:09
Array.prototype.add = function(b){
var a = this.concat(); // clone current object
if(!b.push || !b.length) return a; // if b is not an array, or empty, then return a unchanged
if(!a.length) return b.concat(); // if original is empty, return b
// go through all the elements of b
for(var i = 0; i < b.length; i++){
// if b's value is not in a, then add it
if(a.indexOf(b[i]) == -1) a.push(b[i]);
}
return a;
}
// Example:
console.log([1,2,3].add([3, 4, 5])); // will output [1, 2, 3, 4, 5]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-26 11:38:21
Możesz to osiągnąć po prostu używając podkreślenia.js = > uniq :
array3 = _.uniq(array1.concat(array2))
console.log(array3)
Wydrukuje ["Vijendra", "Singh","Shakya"] .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:54:55
array1.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)
Fajną rzeczą w tym jest wydajność i to, że w ogóle, podczas pracy z tablicami, są metody łańcuchowe, takie jak filtr, Mapa, itp., więc możesz dodać tę linię I będzie ona łączyć i deduplikować array2 z array1 bez konieczności odniesienia do późniejszego (gdy masz metody łańcuchowe, których nie masz), przykład:
someSource()
.reduce(...)
.filter(...)
.map(...)
// and now you want to concat array2 and deduplicate:
.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)
// and keep chaining stuff
.map(...)
.find(...)
// etc
(nie lubię zanieczyszczać tablicy.prototyp i to byłby jedyny sposób respektowania łańcucha-zdefiniowanie nowej funkcji go złamie-więc myślę, że coś takiego jest jedynym sposobem na osiągnięcie tego)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 10:10:01
Nowe rozwiązanie (które wykorzystuje Array.prototype.indexOf
i Array.prototype.concat
):
Array.prototype.uniqueMerge = function( a ) {
for ( var nonDuplicates = [], i = 0, l = a.length; i<l; ++i ) {
if ( this.indexOf( a[i] ) === -1 ) {
nonDuplicates.push( a[i] );
}
}
return this.concat( nonDuplicates )
};
Użycie:
>>> ['Vijendra', 'Singh'].uniqueMerge(['Singh', 'Shakya'])
["Vijendra", "Singh", "Shakya"]
Array.prototyp.indexOf (dla internet Explorera):
Array.prototype.indexOf = Array.prototype.indexOf || function(elt)
{
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;
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-18 11:10:45
W Dojo 1.6 +
var unique = [];
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = array1.concat(array2); // Merged both arrays
dojo.forEach(array3, function(item) {
if (dojo.indexOf(unique, item) > -1) return;
unique.push(item);
});
Update
Zobacz kod roboczy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-12 13:30:21
Połącz nieograniczoną liczbę tablic lub innych tablic i zachowaj unikalność:
function flatMerge() {
return Array.prototype.reduce.call(arguments, function (result, current) {
if (!(current instanceof Array)) {
if (result.indexOf(current) === -1) {
result.push(current);
}
} else {
current.forEach(function (value) {
console.log(value);
if (result.indexOf(value) === -1) {
result.push(value);
}
});
}
return result;
}, []);
}
flatMerge([1,2,3], 4, 4, [3, 2, 1, 5], [7, 6, 8, 9], 5, [4], 2, [3, 2, 5]);
// [1, 2, 3, 4, 5, 7, 6, 8, 9]
flatMerge([1,2,3], [3, 2, 1, 5], [7, 6, 8, 9]);
// [1, 2, 3, 5, 7, 6, 8, 9]
flatMerge(1, 3, 5, 7);
// [1, 3, 5, 7]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-20 18:02:29
Zakładając, że oryginalne tablice nie wymagają deduplikacji, powinno to być dość szybkie, zachować pierwotną kolejność i nie modyfikować oryginalnych tablic...
function arrayMerge(base, addendum){
var out = [].concat(base);
for(var i=0,len=addendum.length;i<len;i++){
if(base.indexOf(addendum[i])<0){
out.push(addendum[i]);
}
}
return out;
}
Użycie:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = arrayMerge(array1, array2);
console.log(array3);
//-> [ 'Vijendra', 'Singh', 'Shakya' ]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 23:27:58
Podejście funkcjonalne z ES2015
Zgodnie z podejściem funkcjonalnym a union
z dwóch Array
S jest tylko składem concat
i filter
. W celu zapewnienia optymalnej wydajności korzystamy z natywnego typu danych Set
, który jest zoptymalizowany pod kątem wyszukiwania właściwości.
W każdym razie, kluczowym pytaniem w połączeniu z funkcją union
jest sposób traktowania duplikatów. Możliwe są następujące permutacje:
Array A + Array B
[unique] + [unique]
[duplicated] + [unique]
[unique] + [duplicated]
[duplicated] + [duplicated]
Pierwsze dwie permutacje są łatwe w obsłudze za pomocą pojedyncza funkcja. Jednak dwa ostatnie są bardziej skomplikowane, ponieważ nie można ich przetwarzać tak długo, jak długo można polegać na wyszukiwaniach Set
. Ponieważ przejście na zwykłą starą właściwość Object
oznaczałoby poważny hit wydajności, następująca implementacja ignoruje trzecią i czwartą permutację. Trzeba by zbudować osobną wersję union
, aby je obsługiwać.
// small, reusable auxiliary functions
const comp = f => g => x => f(g(x));
const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const afrom = apply(Array.from);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
// de-duplication
const dedupe = comp(afrom) (createSet);
// the actual union function
const union = xs => ys => {
const zs = createSet(xs);
return concat(xs) (
filter(x => zs.has(x)
? false
: zs.add(x)
) (ys));
}
// mock data
const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];
// here we go
console.log( "unique/unique", union(dedupe(xs)) (ys) );
console.log( "duplicated/unique", union(xs) (ys) );
Od tego momentu staje się trywialne zaimplementowanie unionn
funkcji, która przyjmuje dowolne liczba tablic (zainspirowana komentarzami naomika):
// small, reusable auxiliary functions
const uncurry = f => (a, b) => f(a) (b);
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc);
const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
// union and unionn
const union = xs => ys => {
const zs = createSet(xs);
return concat(xs) (
filter(x => zs.has(x)
? false
: zs.add(x)
) (ys));
}
const unionn = (head, ...tail) => foldl(union) (head) (tail);
// mock data
const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];
const zs = [0,1,2,3,4,5,6,7,8,9];
// here we go
console.log( unionn(xs, ys, zs) );
Okazuje się, że unionn
jest po prostu foldl
(aka Array.prototype.reduce
), która przyjmuje union
jako swój reduktor. Uwaga: Ponieważ implementacja nie używa dodatkowego akumulatora, spowoduje błąd, gdy zastosujesz go bez argumentów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-11 08:08:28
Najprostszym sposobem na to jest użycie concat()
do scalania tablic, a następnie użycie filter()
do usuwania duplikatów, lub użycie concat()
, a następnie umieszczenie Scalonej tablicy wewnątrz Set()
.
Pierwsza droga:
const firstArray = [1,2, 2];
const secondArray = [3,4];
// now lets merge them
const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4]
//now use filter to remove dups
const removeDuplicates = mergedArray.filter((elem, index) => mergedArray.indexOf(elem) === index); // [1,2,3, 4]
Drugi sposób (ale z wpływami wydajności na interfejs użytkownika):
const firstArray = [1,2, 2];
const secondArray = [3,4];
// now lets merge them
const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4]
const removeDuplicates = new Set(mergedArray);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-10 20:11:37
Wygląda na to, że zaakceptowana odpowiedź jest najwolniejsza w moich testach;
Uwaga scalam 2 tablice obiektów za pomocą klucza
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<button type='button' onclick='doit()'>do it</button>
<script>
function doit(){
var items = [];
var items2 = [];
var itemskeys = {};
for(var i = 0; i < 10000; i++){
items.push({K:i, C:"123"});
itemskeys[i] = i;
}
for(var i = 9000; i < 11000; i++){
items2.push({K:i, C:"123"});
}
console.time('merge');
var res = items.slice(0);
//method1();
method0();
//method2();
console.log(res.length);
console.timeEnd('merge');
function method0(){
for(var i = 0; i < items2.length; i++){
var isok = 1;
var k = items2[i].K;
if(itemskeys[k] == null){
itemskeys[i] = res.length;
res.push(items2[i]);
}
}
}
function method1(){
for(var i = 0; i < items2.length; i++){
var isok = 1;
var k = items2[i].K;
for(var j = 0; j < items.length; j++){
if(items[j].K == k){
isok = 0;
break;
}
}
if(isok) res.push(items2[i]);
}
}
function method2(){
res = res.concat(items2);
for(var i = 0; i < res.length; ++i) {
for(var j = i+1; j < res.length; ++j) {
if(res[i].K === res[j].K)
res.splice(j--, 1);
}
}
}
}
</script>
</body>
</html>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 12:17:41
Dla dobra tego... oto rozwiązanie pojedynczej linii:
const x = [...new Set([['C', 'B'],['B', 'A']].reduce( (a, e) => a.concat(e), []))].sort()
// ['A', 'B', 'C']
Niezbyt czytelny, ale może komuś pomóc:
- stosuje funkcję reduce z początkową wartością akumulatora ustawioną na pustą tablicę.
- funkcja reduce używa concat do dołączania każdej tablicy podrzędnej do tablicy akumulatorów.
- wynik jest przekazywany jako parametr konstruktora do utworzenia nowego
Set
. - operator spreadu jest używany do Konwersji
Set
na / align = "left" / - Funkcja
sort()
zostanie zastosowana do nowej tablicy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-03 21:48:29
Deduplikacja pojedynczych lub scalonych i deduplikacja wielu wejść tablicy. Przykład poniżej.
Useing ES6-Set, for of, destructuring
Napisałem prostą funkcję, która pobiera wiele argumentów tablicy. Czy prawie tak samo jak powyżej rozwiązanie ma tylko bardziej praktyczny przypadek użycia. Ta funkcja nie łączy zduplikowanych wartości tylko do jednej tablicy tak, że może je usunąć na późniejszym etapie.
Krótka definicja funkcji (tylko 9 linii )
/**
* This function merging only arrays unique values. It does not merges arrays in to array with duplicate values at any stage.
*
* @params ...args Function accept multiple array input (merges them to single array with no duplicates)
* it also can be used to filter duplicates in single array
*/
function arrayDeDuplicate(...args){
let set = new Set(); // init Set object (available as of ES6)
for(let arr of args){ // for of loops through values
arr.map((value) => { // map adds each value to Set object
set.add(value); // set.add method adds only unique values
});
}
return [...set]; // destructuring set object back to array object
// alternativly we culd use: return Array.from(set);
}
UŻYJ PRZYKŁADU CODEPEN :
// SCENARIO
let a = [1,2,3,4,5,6];
let b = [4,5,6,7,8,9,10,10,10];
let c = [43,23,1,2,3];
let d = ['a','b','c','d'];
let e = ['b','c','d','e'];
// USEAGE
let uniqueArrayAll = arrayDeDuplicate(a, b, c, d, e);
let uniqueArraySingle = arrayDeDuplicate(b);
// OUTPUT
console.log(uniqueArrayAll); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 43, 23, "a", "b", "c", "d", "e"]
console.log(uniqueArraySingle); // [4, 5, 6, 7, 8, 9, 10]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 03:10:28
Połącz dwie tablice i usuń duplikaty w es6
let arr1 = [3, 5, 2, 2, 5, 5];
let arr2 = [2, 1, 66, 5];
let unique = [...new Set([...arr1,...arr2])];
console.log(unique);
// [ 3, 5, 2, 1, 66 ]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-03 04:09:04