Usuwanie elementów tablicy w JavaScript - usuwanie kontra splatanie


1333

Co stanowi różnicę pomiędzy stosowaniem do deleteoperatora na elemencie tablicy, w przeciwieństwie do używania w Array.splicesposób ?

Na przykład:

myArray = ['a', 'b', 'c', 'd'];

delete myArray[1];
//  or
myArray.splice (1, 1);

Po co w ogóle stosować metodę łączenia, jeśli mogę usuwać elementy tablicy tak jak mogę z obiektami?


3
W przypadku .splicepętli spójrz na to pytanie: Usuń z tablicy w javascript .
Rob W

6
@andynormancx Tak, ale ta odpowiedź została opublikowana następnego dnia i uzyskała o wiele więcej głosów - powiedziałbym, że lepiej napisać, to musi być to.
Camilo Martin

@andynormancx - Nie wydaje się dokładnym duplikatem. Pytanie, które połączyłeś, zasadniczo pyta, dlaczego usunięcie elementu z tablicy (co czyni go rzadkim) nie zmniejszy jego długości. To pytanie dotyczy różnic między deletei Array.prototype.splice.
chharvey

@chharvey zgodził się, a co ważniejsze, jak to pytanie mogło zostać opublikowane 9 lat temu! Sprawia, że ​​czuję się stary, kiedy wrócę tutaj, komentując to
andynormancx

Odpowiedzi:


1692

deleteusunie właściwość obiektu, ale nie zindeksuje tablicy ani nie zaktualizuje jej długości. To sprawia, że ​​wygląda na niezdefiniowany:

> myArray = ['a', 'b', 'c', 'd']
  ["a", "b", "c", "d"]
> delete myArray[0]
  true
> myArray[0]
  undefined

Zauważ, że w rzeczywistości nie jest ustawiony na wartość undefined, a raczej właściwość jest usuwana z tablicy, przez co wydaje się niezdefiniowana. Narzędzia deweloperskie Chrome wyjaśniają to rozróżnienie, drukując emptypodczas logowania tablicy.

> myArray[0]
  undefined
> myArray
  [empty, "b", "c", "d"]

myArray.splice(start, deleteCount) faktycznie usuwa element, ponownie indeksuje tablicę i zmienia jej długość.

> myArray = ['a', 'b', 'c', 'd']
  ["a", "b", "c", "d"]
> myArray.splice(0, 2)
  ["a", "b"]
> myArray
  ["c", "d"]

74
W rzeczywistości, delete nie usunięcia elementu, ale nie reindex tablicy lub zaktualizować swoją długość (która znajduje się już od dawna, ponieważ długość jest zawsze najwyższy wskaźnik + 1).
Felix Kling

3
JSlint nie lubi delete myArray[0] składni „mówiąc oczekiwać operator i zamiast piły«delete». ” Korzystanie splicezalecane.
Oko

21
@Eye: W rzeczywistości JSLint narzeka na brak średnika w poprzedniej linii. I nie możesz tak naprawdę polecić jednego z drugiego, ponieważ robią zupełnie inne rzeczy…
Ry-

3
„Usuń w tym przypadku ustawi tylko element jako niezdefiniowany:” Nie, to jest całkowicie niepoprawne. Istnieje zasadnicza różnica między delete myArray[0]i myArray[0] = undefined. W pierwszym przypadku właściwość jest całkowicie usuwana z obiektu tablicy. W drugim przypadku właściwość pozostaje z wartością undefined.
TJ Crowder

1
Do Twojej wiadomości, narzędzia programistyczne Chrome pokazują słowo kluczowe emptyzamiast undefinedpoprawić rozróżnienie między faktycznie usuniętym (lub niezainicjowanym) elementem tablicy a elementem o rzeczywistej wartości undefined. Zauważ, że jak to mówię, to znaczy, że wyświetla tylko jako emptyi nie odnosi się do prawdziwej wartości o nazwie empty(która nie istnieje).
chharvey

340

Metoda Array.remove ()

John Resig , twórca jQuery, stworzył bardzo przydatną Array.removemetodę, której zawsze używam w swoich projektach.

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

a oto kilka przykładów tego, jak można go użyć:

// Remove the second item from the array
array.remove(1);
// Remove the second-to-last item from the array
array.remove(-2);
// Remove the second and third items from the array
array.remove(1,2);
// Remove the last and second-to-last items from the array
array.remove(-2,-1);

Strona Johna


4
+1 dla Array.remove (). Jednak nie jest zadowolone z przekazywania argumentów łańcuchowych (w przeciwieństwie do większości metod Array, np. [1,2,3].slice('1'); // =[2,3]), Więc bezpieczniej jest zmienić to navar rest = this.slice(parseInt(to || from) + 1 || this.length);
Richard Inglis

1
@tomwrong, w javascript nie ma wątków, a funkcja wykonuje się this.push.apply(this, rest), a następnie zwraca wartość, którą zwróciła
billy

59
To wcale nie odpowiada na pytanie.
Ry-

16
Dlaczego nie użyć po prostu splice ()? Nazwa tej funkcji, nazwy parametrów i wyniki nie są oczywiste. Moje zalecenie to po prostu użyć splajnu (indeks, długość) - (patrz odpowiedź Andy'ego Hume'a)
auco

3
Podana powyżej funkcja działa tak, jak wyjaśniono, ale powoduje niepożądane efekty uboczne podczas iteracji po tablicy z for(var i in array)cyklem. Usunąłem go i zamiast tego użyłem splotu.
alexykot

104

Ponieważ delete usuwa tylko obiekt z elementu w tablicy, długość tablicy nie zmieni się. Splice usuwa obiekt i skraca tablicę.

Poniższy kod wyświetli „a”, „b”, „undefined”, „d”

myArray = ['a', 'b', 'c', 'd']; delete myArray[2];

for (var count = 0; count < myArray.length; count++) {
    alert(myArray[count]);
}

Podczas gdy wyświetli się „a”, „b”, „d”

myArray = ['a', 'b', 'c', 'd']; myArray.splice(2,1);

for (var count = 0; count < myArray.length; count++) {
    alert(myArray[count]);
}

11
świetny przykład, z wyjątkiem dwuznaczności w drugim przykładzie przy użyciu 1,1 - pierwsza 1 odnosi się do indeksu w tablicy, aby rozpocząć łączenie, druga 1 to liczba elementów do usunięcia. Aby usunąć „c” z oryginalnej tablicy, użyjmyArray.splice(2,1)
iancoleman,

68

Natknąłem się na to pytanie, próbując zrozumieć, jak usunąć każde wystąpienie elementu z tablicy. Oto porównanie z splicei deletedo usuwania każdego 'c'z itemstablicy.

var items = ['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'];

while (items.indexOf('c') !== -1) {
  items.splice(items.indexOf('c'), 1);
}

console.log(items); // ["a", "b", "d", "a", "b", "d"]

items = ['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'];

while (items.indexOf('c') !== -1) {
  delete items[items.indexOf('c')];
}

console.log(items); // ["a", "b", undefined, "d", "a", "b", undefined, "d"]


10

splice będzie działać z indeksami numerycznymi.

mając na uwadze, że deletemożna go stosować do innych wskaźników

przykład:

delete myArray['text1'];

9
Kiedy mówisz „jakikolwiek inny rodzaj wskaźników”, nie mówisz już o tablicach, ale raczej o obiektach, o które prosi OP.
Yi Jiang

2
@YiJiang: Tablice są obiektami. Indizes to właściwości. Nie ma różnicy.
Bergi

9

Warto też wspomnieć, że splice działa tylko na tablicach. (Nie można polegać na właściwościach obiektu w celu zachowania zgodnej kolejności).

Aby usunąć parę klucz-wartość z obiektu, usuń jest właściwie tym, czego chcesz:

delete myObj.propName;     // , or:
delete myObj["propName"];  // Equivalent.

delete nie zmienia kolejności kluczy tablicy, więc: var arr = [1,2,3,4,5]; usuń arr [3]; for (var i = 0; i <= arr.length; i ++) console.log (arr [i]); pokaże nieoczekiwane wyniki.
Kristian Williams

To prawda. Więc jeśli nie chcesz pozostawić niezdefiniowanego elementu w tej lokalizacji, NIE używaj delete na klawiszach tablicy! Pierwotnie dodałem ten komentarz, aby zamieścić odniesienie do prawidłowego użycia delete.
jtrick

ale dlaczego skasowanie spowoduje nieoczekiwany wynik?
Alex

9

usuń połączenie Vs

po usunięciu elementu z tablicy

var arr = [1,2,3,4]; delete arr[2]; //result [1, 2, 3:, 4]
console.log(arr)

kiedy się splatasz

var arr = [1,2,3,4]; arr.splice(1,1); //result [1, 3, 4]
console.log(arr);

w przypadku usuwania Element zostanie usunięty , ale indeks pozostaje pusty

natomiast w przypadku łączenia element jest usuwany, a indeks pozostałych elementów jest odpowiednio zmniejszany


8

Jak wspomniano wiele razy powyżej, używanie splice()wydaje się być idealnym dopasowaniem. Dokumentacja w Mozilli:

splice()Sposób zmienia zawartość tablicy poprzez usunięcie elementów i / lub dodania nowych elementów.

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];

myFish.splice(2, 0, 'drum'); 
// myFish is ["angel", "clown", "drum", "mandarin", "sturgeon"]

myFish.splice(2, 1); 
// myFish is ["angel", "clown", "mandarin", "sturgeon"]

Składnia

array.splice(start)
array.splice(start, deleteCount)
array.splice(start, deleteCount, item1, item2, ...)

Parametry

początek

Indeks, od którego należy zacząć zmieniać tablicę. Jeśli wartość jest większa niż długość tablicy, rzeczywisty indeks początkowy zostanie ustawiony na długość tablicy. Jeśli negatywne, zacznie tyle elementów od końca.

deleteCount

Liczba całkowita wskazująca liczbę starych elementów tablicy do usunięcia. Jeśli deleteCount ma wartość 0, żadne elementy nie są usuwane. W takim przypadku należy podać co najmniej jeden nowy element. Jeśli deleteCount jest większa niż liczba elementów pozostałych w tablicy, zaczynając od początku, wówczas wszystkie elementy do końca tablicy zostaną usunięte.

Jeśli deleteCount zostanie pominięte, deleteCount będzie równe (arr.length - start).

item1, item2, ...

Elementy do dodania do tablicy, zaczynając od indeksu początkowego. Jeśli nie określisz żadnych elementów, splice()usuniesz tylko elementy z tablicy.

Zwracana wartość

Tablica zawierająca usunięte elementy. Jeśli tylko jeden element zostanie usunięty, zwracana jest tablica jednego elementu. Jeśli nie zostaną usunięte żadne elementy, zwracana jest pusta tablica.

[...]


@ downvoter: dlaczego downvote? chcesz wyjaśnić, czy nie?
serv-inc

7

delete działa jak sytuacja nierzeczywista, po prostu usuwa element, ale długość tablicy pozostaje taka sama:

przykład z terminala węzłowego:

> var arr = ["a","b","c","d"];
> delete arr[2]
true
> arr
[ 'a', 'b', , 'd', 'e' ]

Oto funkcja usuwania elementu tablicy według indeksu, używając slice () , bierze arr jako pierwszy argument, a indeks elementu, który chcesz usunąć, jako drugi argument. Jak widać, faktycznie usuwa on element tablicy i zmniejsza długość tablicy o 1

function(arr,arrIndex){
    return arr.slice(0,arrIndex).concat(arr.slice(arrIndex + 1));
}

Powyższa funkcja polega na przejściu wszystkich elementów do indeksu i wszystkich elementów po indeksie, a następnie połączeniu ich razem i zwrócenia wyniku.

Oto przykład wykorzystania powyższej funkcji jako modułu węzła, przydanie się terminalowi będzie przydatne:

> var arr = ["a","b","c","d"]
> arr
[ 'a', 'b', 'c', 'd' ]
> arr.length
4 
> var arrayRemoveIndex = require("./lib/array_remove_index");
> var newArray = arrayRemoveIndex(arr,arr.indexOf('c'))
> newArray
[ 'a', 'b', 'd' ] // c ya later
> newArray.length
3

pamiętaj, że to nie zadziała w jednej tablicy z duplikatami, ponieważ indexOf („c”) dostanie tylko pierwsze wystąpienie, a jedynie podzieli i usunie pierwsze znalezione „c”.


6

Jeśli chcesz iterować dużą tablicę i selektywnie usuwać elementy, kosztowne byłoby wywoływanie funkcji splice () dla każdego usunięcia, ponieważ funkcja splice () musiałaby za każdym razem ponownie indeksować kolejne elementy. Ponieważ tablice są asocjatywne w Javascripcie, bardziej efektywne byłoby usunięcie poszczególnych elementów, a następnie ponowne zindeksowanie tablicy.

Możesz to zrobić, budując nową tablicę. na przykład

function reindexArray( array )
{
       var result = [];
        for( var key in array )
                result.push( array[key] );
        return result;
};

Ale nie sądzę, że możesz zmodyfikować kluczowe wartości w oryginalnej tablicy, co byłoby bardziej wydajne - wygląda na to, że będziesz musiał utworzyć nową tablicę.

Zauważ, że nie musisz sprawdzać „niezdefiniowanych” wpisów, ponieważ tak naprawdę nie istnieją, a pętla for ich nie zwraca. Jest to artefakt drukowania macierzy, który wyświetla je jako niezdefiniowane. Nie wydają się istnieć w pamięci.

Byłoby miło, gdybyś mógł użyć czegoś takiego jak slice (), co byłoby szybsze, ale nie indeksuje się ponownie. Czy ktoś zna lepszy sposób?


W rzeczywistości możesz to zrobić w następujący sposób, co jest prawdopodobnie bardziej wydajne i wydajne:

reindexArray : function( array )
{
    var index = 0;                          // The index where the element should be
    for( var key in array )                 // Iterate the array
    {
        if( parseInt( key ) !== index )     // If the element is out of sequence
        {
            array[index] = array[key];      // Move it to the correct, earlier position in the array
            ++index;                        // Update the index
        }
    }

    array.splice( index );  // Remove any remaining elements (These will be duplicates of earlier items)
},

Uważam, że indeks ++; musi się zdarzyć poza „jeśli”. Dokonywanie edycji
mishal153

6

możesz użyć czegoś takiego

var my_array = [1,2,3,4,5,6];
delete my_array[4];
console.log(my_array.filter(function(a){return typeof a !== 'undefined';})); // [1,2,3,4,6]


jest to bardziej intuicyjne niż w sliceprzypadku tła funkcjonalnego (prawdopodobnie mniej wydajnego).
jethro

3

Dlaczego nie po prostu filtrować? Myślę, że jest to najwyraźniejszy sposób rozważenia tablic w js.

myArray = myArray.filter(function(item){
    return item.anProperty != whoShouldBeDeleted
});

Co powiesz na tablicę zawierającą setki (jeśli nie tysiące) rekordów, z których trzeba usunąć tylko 3 z nich?
Joel Hernandez,

Słuszna uwaga. Używam tej metody do rzadkich tablic, których długość nie przekracza 200 lub 300 i działa bardzo dobrze. Myślę jednak, że biblioteki takie jak podkreślenie powinny być preferowane, jeśli musisz zarządzać takimi większymi tablicami.
Asqan,

1
Wydaje mi się jednak znacznie ładniejszy niż deletelub slice.
Juneyoung Oh

3

Różnicę można zobaczyć, rejestrując długość każdej tablicy po zastosowaniu deleteoperatora i splice()metody. Na przykład:

usuń operatora

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3];

console.log(trees); // ["redwood", "bay", "cedar", empty, "maple"]
console.log(trees.length); // 5

deleteOperator usuwa element z tablicy, ale „Znacznik” elementu wciąż istnieje. oakzostał usunięty, ale nadal zajmuje miejsce w tablicy. Z tego powodu długość tablicy wynosi 5.

metoda splice ()

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.splice(3,1);

console.log(trees); // ["redwood", "bay", "cedar", "maple"]
console.log(trees.length); // 4

splice()Sposób całkowicie eliminuje wartość docelową oraz w „zastępczy” oraz. oakzostał usunięty, podobnie jak miejsce, które zajmowało w tablicy. Długość tablicy wynosi teraz 4.


2
function remove_array_value(array, value) {
    var index = array.indexOf(value);
    if (index >= 0) {
        array.splice(index, 1);
        reindex_array(array);
    }
}
function reindex_array(array) {
   var result = [];
    for (var key in array) {
        result.push(array[key]);
    }
    return result;
}

przykład:

var example_arr = ['apple', 'banana', 'lemon'];   // length = 3
remove_array_value(example_arr, 'banana');

banan jest usuwany, a długość tablicy = 2


2

Są to różne rzeczy, które mają różne cele.

splicejest specyficzne dla tablicy i użyte do usunięcia usuwa wpisy z tablicy i przesuwa wszystkie poprzednie wpisy w górę, aby wypełnić lukę. (Można go również użyć do wstawienia wpisów lub obu jednocześnie.) spliceZmieni lengthtablicę (zakładając, że nie jest to wywołanie braku operacji:) theArray.splice(x, 0).

deletenie zależy od tablicy; jest przeznaczony do użycia na obiektach: usuwa właściwość (parę klucz / wartość) z obiektu, na którym go używasz. Ma to zastosowanie tylko do tablic, ponieważ standardowe (np. Nietypowe) tablice w JavaScript nie są tak naprawdę tablicami *, są to obiekty ze specjalną obsługą niektórych właściwości, takich jak te, których nazwy to „indeksy tablic” (które są zdefiniowane jako nazwy ciągów „... których wartość liczbowa inależy do zakresu +0 ≤ i < 2^32-1”) i length. Kiedy używasz deletedo usunięcia pozycji tablicy, wszystko, co robi, to usunięcie pozycji; nie przesuwa kolejnych wpisów, aby wypełnić lukę, więc tablica staje się „rzadka” (całkowicie brakuje niektórych wpisów). Nie ma wpływu na length.

Kilka aktualnych odpowiedzi na to pytanie błędnie stwierdza, że ​​użycie delete„ustawia wpis na undefined”. To nie jest poprawne To usuwa wpis (właściwość) całkowicie, pozostawiając lukę.

Użyjmy kodu, aby zilustrować różnice:

console.log("Using `splice`:");
var a = ["a", "b", "c", "d", "e"];
console.log(a.length);            // 5
a.splice(0, 1);
console.log(a.length);            // 4
console.log(a[0]);                // "b"

console.log("Using `delete`");
var a = ["a", "b", "c", "d", "e"];
console.log(a.length);            // 5
delete a[0];
console.log(a.length);            // still 5
console.log(a[0]);                // undefined
console.log("0" in a);            // false
console.log(a.hasOwnProperty(0)); // false

console.log("Setting to `undefined`");
var a = ["a", "b", "c", "d", "e"];
console.log(a.length);            // 5
a[0] = undefined;
console.log(a.length);            // still 5
console.log(a[0]);                // undefined
console.log("0" in a);            // true
console.log(a.hasOwnProperty(0)); // true


* (to post na moim anemicznym małym blogu)


2

Obecnie są na to dwa sposoby

  1. using splice ()

    arrayObject.splice(index, 1);

  2. za pomocą delete

    delete arrayObject[index];

Zawsze jednak sugeruję używanie splajnu dla obiektów tablicowych i usuwania dla atrybutów obiektów, ponieważ delete nie aktualizuje długości tablicy.


1

OK, wyobraź sobie, że mamy tę tablicę poniżej:

const arr = [1, 2, 3, 4, 5];

Najpierw usuńmy:

delete arr[1];

i to jest wynik:

[1, empty, 3, 4, 5];

pusty! i zdobądźmy to:

arr[1]; //undefined

Oznacza to, że tylko wartość została usunięta i jest teraz niezdefiniowana , więc długość jest taka sama, a także zwróci true ...

Zresetujmy naszą tablicę i zróbmy to tym razem:

arr.splice(1, 1);

i tym razem jest to wynik:

[1, 3, 4, 5];

Jak widać długość tablicy zmieniła się i arr[1]wynosi teraz 3 ...

Zwróci również usunięty element w tablicy, która [3]w tym przypadku ...


1

Inni już poprawnie się deletez tym porównalisplice .

Innym interesującym porównanie jest deletekontra undefined: usunięty element tablicy zużywa mniej pamięci niż jeden, który jest po prostu ustawiony undefined;

Na przykład ten kod nie zakończy się:

let y = 1;
let ary = [];
console.log("Fatal Error Coming Soon");
while (y < 4294967295)
{
    ary.push(y);
    ary[y] = undefined;
    y += 1;
}
console(ary.length);

Powoduje ten błąd:

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory.

Jak widać, undefinedfaktycznie zajmuje pamięć sterty.

Jednak jeśli również deleteelement arytowy (zamiast po prostu ustawiając go na undefined), kod powoli się skończy:

let x = 1;
let ary = [];
console.log("This will take a while, but it will eventually finish successfully.");
while (x < 4294967295)
{
    ary.push(x);
    ary[x] = undefined;
    delete ary[x];
    x += 1;
}
console.log(`Success, array-length: ${ary.length}.`);

Są to skrajne przykłady, ale podkreślają, deleteże nigdzie nie wspomniałem.


1

Jeśli masz małą tablicę, możesz użyć filter:

myArray = ['a', 'b', 'c', 'd'];
myArray = myArray.filter(x => x !== 'b');

0

Najłatwiejszy sposób to prawdopodobnie

var myArray = ['a', 'b', 'c', 'd'];
delete myArray[1]; // ['a', undefined, 'c', 'd']. Then use lodash compact method to remove false, null, 0, "", undefined and NaN
myArray = _.compact(myArray); ['a', 'c', 'd'];

Mam nadzieję że to pomoże. Odniesienie: https://lodash.com/docs#compact


1
Gdyby ktoś natknął się na to zastanawianie się compact... nie ma potrzeby lodash. SpróbujmyArray.filter(function(n){return n;})
dat

0

Dla tych, którzy chcą korzystać z Lodash, można użyć: myArray = _.without(myArray, itemToRemove)

Lub jak używam w Angular2

import { without } from 'lodash';
...
myArray = without(myArray, itemToRemove);
...

0

delete : delete usunie właściwość obiektu, ale nie będzie ponownie indeksować tablicy ani aktualizować jej długości. To sprawia, że ​​wygląda na niezdefiniowany:

splice : faktycznie usuwa element, ponownie indeksuje tablicę i zmienia jej długość.

Usuń element z ostatniego

arrName.pop();

Usuń element od pierwszego

arrName.shift();

Usuń ze środka

arrName.splice(starting index,number of element you wnt to delete);

Ex: arrName.splice(1,1);

Usuń jeden element z ostatniego

arrName.splice(-1);

Usuń za pomocą numeru indeksu tablicy

 delete arrName[1];

0

Jeśli żądany element do usunięcia znajduje się w środku (powiedzmy, że chcemy usunąć „c”, którego indeks wynosi 1), możesz użyć:

var arr = ['a','b','c'];
var indexToDelete = 1;
var newArray = arr.slice(0,indexToDelete).combine(arr.slice(indexToDelete+1, arr.length))

0

IndexOfakceptuje również typ referencyjny. Załóżmy następujący scenariusz:

var arr = [{item: 1}, {item: 2}, {item: 3}];
var found = find(2, 3); //pseudo code: will return [{item: 2}, {item:3}]
var l = found.length;

while(l--) {
   var index = arr.indexOf(found[l])
      arr.splice(index, 1);
   }
   
console.log(arr.length); //1

Różnie:

var item2 = findUnique(2); //will return {item: 2}
var l = arr.length;
var found = false;
  while(!found && l--) {
  found = arr[l] === item2;
}

console.log(l, arr[l]);// l is index, arr[l] is the item you look for

-1
function deleteFromArray(array, indexToDelete){
  var remain = new Array();
  for(var i in array){
    if(array[i] == indexToDelete){
      continue;
    }
    remain.push(array[i]);
  }
  return remain;
}

myArray = ['a', 'b', 'c', 'd'];
deleteFromArray(myArray , 0);

// wynik: myArray = ['b', 'c', 'd'];


@ChrisDennis dlaczego? (bez zamierzonego sarkazmu lub złośliwości, to szczere pytanie)
Chris Bier

Poza tym, że ta odpowiedź nie odnosi się do pytania OP
Chris Bier
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.