Как получить разницу между двумя массивами в JavaScript?

есть ли способ вернуть разницу между двумя массивами в JavaScript?

например:

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

// need ["c", "d"]

любые советы с благодарностью.

30 ответов


Я предполагаю, что вы сравниваете обычный массив. Если нет, вам нужно изменить на петли к for .. в петли.

function arr_diff (a1, a2) {

    var a = [], diff = [];

    for (var i = 0; i < a1.length; i++) {
        a[a1[i]] = true;
    }

    for (var i = 0; i < a2.length; i++) {
        if (a[a2[i]]) {
            delete a[a2[i]];
        } else {
            a[a2[i]] = true;
        }
    }

    for (var k in a) {
        diff.push(k);
    }

    return diff;
}

console.log(arr_diff(['a', 'b'], ['a', 'b', 'c', 'd']));
console.log(arr_diff("abcd", "abcde"));
console.log(arr_diff("zxc", "zxc"));

лучшим решением, если вы не заботитесь о обратной совместимости, является использование фильтра. Но все же это решение работает.


Array.prototype.diff = function(a) {
    return this.filter(function(i) {return a.indexOf(i) < 0;});
};

////////////////////  
// Examples  
////////////////////

[1,2,3,4,5,6].diff( [3,4,5] );  
// => [1, 2, 6]

["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);  
// => ["test5", "test6"]

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return a.indexOf(i) < 0;});
};

////////////////////  
// Examples  
////////////////////

var dif1 = [1,2,3,4,5,6].diff( [3,4,5] );  
console.log(dif1); // => [1, 2, 6]


var dif2 = ["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);  
console.log(dif2); // => ["test5", "test6"]

Примечание indexOf и фильтр недоступны в ie до ie9.


есть лучший способ использовать ES7:

пересечение

 let intersection = arr1.filter(x => arr2.includes(x));

Intersection difference Venn Diagram

на [1,2,3] [2,3] это даст [2,3]. С другой стороны, для [1,2,3] [2,3,5] вернет то же самое.

разница

let difference = arr1.filter(x => !arr2.includes(x));

Right difference Venn Diagram

на [1,2,3] [2,3] это даст [1]. С другой стороны, для [1,2,3] [2,3,5] вернет то же самое вещь.

на симметрическая разность, вы можете сделать:

let difference = arr1
                 .filter(x => !arr2.includes(x))
                 .concat(arr2.filter(x => !arr1.includes(x)));

Symmetric difference Venn Diagram

таким образом, вы получите массив, содержащий все элементы arr1, которые не в arr2 и наоборот

как отметил @Joshaven Potter в своем ответе,вы можете добавить это в массив.прототип, поэтому его можно использовать следующим образом:

Array.prototype.diff = arr1.filter(x => arr2.includes(x));
[1, 2, 3].diff([2, 3])

Это, безусловно, самый простой способ получить именно тот результат, который вы ищете, с помощью jQuery:

var diff = $(old_array).not(new_array).get();

diff теперь содержит то, что был в old_array это не new_array


метод разницы в подчеркивании (или его замена,Lo-Dash) могут сделать это:

(R)eturns the values from array that are not present in the other arrays

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]

Как и в любой функции подчеркивания, вы также можете использовать его в более объектно-ориентированном стиле:

_([1, 2, 3, 4, 5]).difference([5, 2, 10]);

Простой JavaScript

есть два возможных intepretations для "разницы". Я позволю тебе выбрать, какой ты хочешь. Скажите, что у вас есть:

var a1 = ['a', 'b'     ];
var a2 = [     'b', 'c'];
  1. если вы хотите получить ['a'] используйте эту функцию:

    function difference(a1, a2) {
      var result = [];
      for (var i = 0; i < a1.length; i++) {
        if (a2.indexOf(a1[i]) === -1) {
          result.push(a1[i]);
        }
      }
      return result;
    }
    
  2. если вы хотите получить ['a', 'c'] (все элементы, содержащиеся в или a1 или a2, но не оба -- так называемый симметрическая разность), используйте это функция:

    function symmetricDifference(a1, a2) {
      var result = [];
      for (var i = 0; i < a1.length; i++) {
        if (a2.indexOf(a1[i]) === -1) {
          result.push(a1[i]);
        }
      }
      for (i = 0; i < a2.length; i++) {
        if (a1.indexOf(a2[i]) === -1) {
          result.push(a2[i]);
        }
      }
      return result;
    }
    

Lodash / Подчеркивание

если вы используете lodash, вы можете использовать _.difference(a1, a2) (Пример 1 выше) или _.xor(a1, a2) (случай 2).

если вы используете нижнее подчеркивание.JS, вы можете использовать _.difference(a1, a2) функции для случая 1.

ES6 Set, для очень больших массивов

код выше работает во всех браузерах. Однако для больших массивов более 10 000 элементов, он становится довольно медленным, потому что имеет сложность O(n2). Во многих современных браузерах мы можем воспользоваться ES6 Set объект, чтобы ускорить вещи. Лодашь автоматически использует Set когда он доступен. Если вы не используете lodash, используйте следующую реализацию, вдохновленную Аксель Rauschmayer после:

function difference(a1, a2) {
  var a2Set = new Set(a2);
  return a1.filter(function(x) { return !a2Set.has(x); });
}

function symmetricDifference(a1, a2) {
  return difference(a1, a2).concat(difference(a2, a1));
}

Примечания

поведение для всех примеров может быть удивительным или неочевидным, если вы заботитесь о -0, +0, NaN или разреженные массивы. (Для большинства применений, это не имеет значения.)


можно использовать Set в этом случае. Он оптимизирован для этого вида деятельности (соединения, пересечения, разницы).

убедитесь, что он применяется к вашему случаю, как только он не допускает дубликатов.

var a = new JS.Set([1,2,3,4,5,6,7,8,9]);
var b = new JS.Set([2,4,6,8]);

a.difference(b)
// -> Set{1,3,5,7,9}

function diff(a1, a2) {
  return a1.concat(a2).filter(function(val, index, arr){
    return arr.indexOf(val) === arr.lastIndexOf(val);
  });
}

объедините оба массива, уникальные значения появятся только один раз, поэтому indexOf() будет таким же, как lastIndexOf().


чтобы вычесть один массив из другого, просто используйте фрагмент ниже:

var a1 = ['1','2','3','4','6'];
var a2 = ['3','4','5'];

var items = new Array();

items = jQuery.grep(a1,function (item) {
    return jQuery.inArray(item, a2) < 0;
});

он вернется ['1,'2','6'] это элементы первого массива, которые не существуют во втором.

поэтому, согласно вашему образцу проблемы, следующий код является точным решением:

var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];

var _array = new Array();

_array = jQuery.grep(array2, function (item) {
     return jQuery.inArray(item, array1) < 0;
});

решение с использованием indexOf() будет нормально для небольших массивов, но по мере их роста производительность алгоритма приближается O(n^2). Вот решение, которое будет работать лучше для очень больших массивов, используя объекты в качестве ассоциативных массивов для хранения записей массива в качестве ключей; он также автоматически устраняет дубликаты записей, но работает только со строковыми значениями (или значениями, которые могут быть безопасно сохранены в виде строк):

function arrayDiff(a1, a2) {
  var o1={}, o2={}, diff=[], i, len, k;
  for (i=0, len=a1.length; i<len; i++) { o1[a1[i]] = true; }
  for (i=0, len=a2.length; i<len; i++) { o2[a2[i]] = true; }
  for (k in o1) { if (!(k in o2)) { diff.push(k); } }
  for (k in o2) { if (!(k in o1)) { diff.push(k); } }
  return diff;
}

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
arrayDiff(a1, a2); // => ['c', 'd']
arrayDiff(a2, a1); // => ['c', 'd']

функциональный подход с ES2015

вычисление difference между двумя массивами находится один из Set операции. Этот термин уже указывает на то, что уроженца Set тип должен использоваться, чтобы увеличить скорость поиска. Во всяком случае, есть три перестановки, когда вы вычисляете разницу между двумя наборами:

[+left difference] [-intersection] [-right difference]
[-left difference] [-intersection] [+right difference]
[+left difference] [-intersection] [+right difference]

вот функциональное решение, которое отражает эти перестановки.

слева difference:

// small, reusable auxiliary functions

const apply = f => x => f(x);
const flip = f => y => x => f(x) (y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// left difference

const differencel = xs => ys => {
  const zs = createSet(ys);
  return filter(x => zs.has(x)
     ? false
     : true
  ) (xs);
};


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];


// run the computation

console.log( differencel(xs) (ys) );

право difference:

differencer тривиально. Это просто differencel С зеркально аргументы. Вы можете написать функцию для удобства: const differencer = flip(differencel). Вот и все!

симметричного difference:

теперь, когда у нас есть левый и правый, реализуя симметричный difference также становится тривиальным:

// small, reusable auxiliary functions

const apply = f => x => f(x);
const flip = f => y => x => f(x) (y);
const concat = y => xs => xs.concat(y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// left difference

const differencel = xs => ys => {
  const zs = createSet(ys);
  return filter(x => zs.has(x)
     ? false
     : true
  ) (xs);
};


// symmetric difference

const difference = ys => xs =>
 concat(differencel(xs) (ys)) (flip(differencel) (xs) (ys));

// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];


// run the computation

console.log( difference(xs) (ys) );

Я думаю, этот пример является хорошей отправной точкой для получите впечатление, что означает функциональное программирование:

Программирование с помощью строительных блоков, которые могут быть подключены друг к другу различными способами.


С приходом ES6 с наборами и оператором splat (на момент работы работает только в Firefox, проверьте таблица совместимости), вы можете написать следующий один вкладыш:

var a = ['a', 'b', 'c', 'd'];
var b = ['a', 'b'];
var b1 = new Set(b);
var difference = [...new Set([...a].filter(x => !b1.has(x)))];

что приведет к [ "c", "d" ].


приведенный выше ответ Джошавена Поттера велик. Но он возвращает элементы в массиве B, которые не находятся в массиве C, но не наоборот. Например, если var a=[1,2,3,4,5,6].diff( [3,4,5,7]); затем он выведет:==>[1,2,6], а не [1,2,6,7], что является фактической разницей между ними. Вы все еще можете использовать код Поттера выше, но просто повторить сравнение еще раз назад:

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return !(a.indexOf(i) > -1);});
};

////////////////////  
// Examples  
////////////////////

var a=[1,2,3,4,5,6].diff( [3,4,5,7]);
var b=[3,4,5,7].diff([1,2,3,4,5,6]);
var c=a.concat(b);
console.log(c);

Это должно вывести:[ 1, 2, 6, 7 ]


другой способ решить проблему

function diffArray(arr1, arr2) {
    return arr1.concat(arr2).filter(function (val) {
        if (!(arr1.includes(val) && arr2.includes(val)))
            return val;
    });
}

diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]);    // return [7, 4, 5]

Array.prototype.difference = function(e) {
    return this.filter(function(i) {return e.indexOf(i) < 0;});
};

eg:- 

[1,2,3,4,5,6,7].difference( [3,4,5] );  
 => [1, 2, 6 , 7]

очень простое решение с функцией фильтра JavaScript:

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

function diffArray(arr1, arr2) {
  var newArr = [];
  var myArr = arr1.concat(arr2);
  
    newArr = myArr.filter(function(item){
      return arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0;
    });
   alert(newArr);
}

diffArray(a1, a2);

Как насчет этого:

Array.prototype.contains = function(needle){
  for (var i=0; i<this.length; i++)
    if (this[i] == needle) return true;

  return false;
} 

Array.prototype.diff = function(compare) {
    return this.filter(function(elem) {return !compare.contains(elem);})
}

var a = new Array(1,4,7, 9);
var b = new Array(4, 8, 7);
alert(a.diff(b));

таким образом, вы можете сделать array1.diff(array2) чтобы получить их разницу (ужасная сложность времени для алгоритма, хотя-O (array1.длина X массив2.длина) я считаю)


использование http://phrogz.net/JS/ArraySetMath.js Вы можете:

var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];

var array3 = array2.subtract( array1 );
// ["test5", "test6"]

var array4 = array1.exclusion( array2 );
// ["test5", "test6"]

  • чистое решение JavaScript (без библиотек)
  • совместимость со старыми браузерами (не использовать filter)
  • O (n^2)
  • дополнительно fn параметр обратного вызова, который позволяет указать, как сравнивать элементы массива

function diff(a, b, fn){
    var max = Math.max(a.length, b.length);
        d = [];
    fn = typeof fn === 'function' ? fn : false
    for(var i=0; i < max; i++){
        var ac = i < a.length ? a[i] : undefined
            bc = i < b.length ? b[i] : undefined;
        for(var k=0; k < max; k++){
            ac = ac === undefined || (k < b.length && (fn ? fn(ac, b[k]) : ac == b[k])) ? undefined : ac;
            bc = bc === undefined || (k < a.length && (fn ? fn(bc, a[k]) : bc == a[k])) ? undefined : bc;
            if(ac == undefined && bc == undefined) break;
        }
        ac !== undefined && d.push(ac);
        bc !== undefined && d.push(bc);
    }
    return d;
}

alert(
    "Test 1: " + 
    diff(
        [1, 2, 3, 4],
        [1, 4, 5, 6, 7]
      ).join(', ') +
    "\nTest 2: " +
    diff(
        [{id:'a',toString:function(){return this.id}},{id:'b',toString:function(){return this.id}},{id:'c',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
        [{id:'a',toString:function(){return this.id}},{id:'e',toString:function(){return this.id}},{id:'f',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
        function(a, b){ return a.id == b.id; }
    ).join(', ')
);

это работает: в основном объединить два массива, искать дубликаты и толкать то, что не дублируется в новый массив, который является разницей.

function diff(arr1, arr2) {
  var newArr = [];
  var arr = arr1.concat(arr2);
  
  for (var i in arr){
    var f = arr[i];
    var t = 0;
    for (j=0; j<arr.length; j++){
      if(arr[j] === f){
        t++; 
        }
    }
    if (t === 1){
      newArr.push(f);
        }
  } 
  return newArr;
}

function diffArray(arr1, arr2) {
  var newArr = arr1.concat(arr2);
  return newArr.filter(function(i){
    return newArr.indexOf(i) == newArr.lastIndexOf(i);
  });
}

это работает для меня


просто думать... ради вызова; -) будет ли это работать... (для базовых массивов строк, чисел и т. д.) нет вложенных массивов

function diffArrays(arr1, arr2, returnUnion){
  var ret = [];
  var test = {};
  var bigArray, smallArray, key;
  if(arr1.length >= arr2.length){
    bigArray = arr1;
    smallArray = arr2;
  } else {
    bigArray = arr2;
    smallArray = arr1;
  }
  for(var i=0;i<bigArray.length;i++){
    key = bigArray[i];
    test[key] = true;
  }
  if(!returnUnion){
    //diffing
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = null;
      }
    }
  } else {
    //union
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = true;
      }
    }
  }
  for(var i in test){
    ret.push(i);
  }
  return ret;
}

array1 = "test1", "test2","test3", "test4", "test7"
array2 = "test1", "test2","test3","test4", "test5", "test6"
diffArray = diffArrays(array1, array2);
//returns ["test5","test6","test7"]

diffArray = diffArrays(array1, array2, true);
//returns ["test1", "test2","test3","test4", "test5", "test6","test7"]

обратите внимание, что сортировка, скорее всего, не будет такой, как указано выше... но при желании звоните .sort () в массиве для сортировки.


littlebit исправить для лучшего ответа

function arr_diff(a1, a2)
{
  var a=[], diff=[];
  for(var i=0;i<a1.length;i++)
    a[a1[i]]=a1[i];
  for(var i=0;i<a2.length;i++)
    if(a[a2[i]]) delete a[a2[i]];
    else a[a2[i]]=a2[i];
  for(var k in a)
   diff.push(a[k]);
  return diff;
}

это будет учитывать текущий тип элемента. b / c когда мы делаем A[a1[i]], он преобразует значение в строку из своего значения oroginal, поэтому мы потеряли фактическое значение.


Это было вдохновлено принятым ответом мыслителя, но ответ мыслителя, похоже, предполагает, что массивы являются наборами. Он разваливается, если массивы [ "1", "2" ] и [ "1", "1", "2", "2" ]

разница между этими массивами составляет [ "1", "2" ]. Следующее решение-O (n*n), поэтому не идеально, но если у вас большие массивы, у него есть преимущества памяти над решением мыслителя.

если вы имеете дело с наборами, в первую очередь, решение мыслителя, безусловно, лучше. Если у вас есть более новая версия Javascript с доступом к фильтрам, вы также должны использовать их. Это только для тех, кто не имеет дело с наборами и использует более старую версию JavaScript (по какой-либо причине)...

if (!Array.prototype.diff) { 
    Array.prototype.diff = function (array) {
        // if the other array is a falsy value, return a copy of this array
        if ((!array) || (!Array.prototype.isPrototypeOf(array))) { 
            return this.slice(0);
        }

        var diff = [];
        var original = this.slice(0);

        for(var i=0; i < array.length; ++i) {
            var index = original.indexOf(array[i]);
            if (index > -1) { 
                original.splice(index, 1);
            } else { 
                diff.push(array[i]);
            }
        }

        for (var i=0; i < original.length; ++i) {
            diff.push(original[i]);
        }
        return diff;
    }
}   

function diff(arr1, arr2) {
  var filteredArr1 = arr1.filter(function(ele) {
    return arr2.indexOf(ele) == -1;
  });

  var filteredArr2 = arr2.filter(function(ele) {
    return arr1.indexOf(ele) == -1;
  });
  return filteredArr1.concat(filteredArr2);
}

diff([1, "calf", 3, "piglet"], [1, "calf", 3, 4]); // Log ["piglet",4]

если массивы не имеют простых типов, то один из приведенных выше ответов может быть адаптирован:

Array.prototype.diff = function(a) {
        return this.filter(function(i) {return a.map(function(e) { return JSON.stringify(e); }).indexOf(JSON.stringify(i)) < 0;});
    };

этот метод работает с массивами сложных объектов.


для получения симметрическая разность вам нужно сравнить массивы в обоих направлениях (или во всех отношениях в случае нескольких массивов)

enter image description here


ES7 (ECMAScript 2016)

// diff between just two arrays:
function arrayDiff(a, b) {
    return [
        ...a.filter(x => !b.includes(x)),
        ...b.filter(x => !a.includes(x))
    ];
}

// diff between multiple arrays:
function arrayDiff(...arrays) {
    return [].concat(...arrays.map( (arr, i) => {
        const others = arrays.slice(0);
        others.splice(i, 1);
        const unique = [...new Set([].concat(...others))];
        return arr.filter(x => !unique.includes(x));
    }));
}

ES6 (ECMAScript 2015)

// diff between just two arrays:
function arrayDiff(a, b) {
    return [
        ...a.filter(x => b.indexOf(x) === -1),
        ...b.filter(x => a.indexOf(x) === -1)
    ];
}

// diff between multiple arrays:
function arrayDiff(...arrays) {
    return [].concat(...arrays.map( (arr, i) => {
        const others = arrays.slice(0);
        others.splice(i, 1);
        const unique = [...new Set([].concat(...others))];
        return arr.filter(x => unique.indexOf(x) === -1);
    }));
}

ES5 (ECMAScript 5.1)

// diff between just two arrays:
function arrayDiff(a, b) {
    var arrays = Array.prototype.slice.call(arguments);
    var diff = [];

    arrays.forEach(function(arr, i) {
        var other = i === 1 ? a : b;
        arr.forEach(function(x) {
            if (other.indexOf(x) === -1) {
                diff.push(x);
            }
        });
    })

    return diff;
}

// diff between multiple arrays:
function arrayDiff() {
    var arrays = Array.prototype.slice.call(arguments);
    var diff = [];

    arrays.forEach(function(arr, i) {
        var others = arrays.slice(0);
        others.splice(i, 1);
        var otherValues = Array.prototype.concat.apply([], others);
        var unique = otherValues.filter(function (x, j) { 
            return otherValues.indexOf(x) === j; 
        });
        diff = diff.concat(arr.filter(x => unique.indexOf(x) === -1));
    });
    return diff;
}

пример:

// diff between two arrays:
const a = ['a', 'd', 'e'];
const b = ['a', 'b', 'c', 'd'];
arrayDiff(a, b); // (3) ["e", "b", "c"]

// diff between multiple arrays
const a = ['b', 'c', 'd', 'e', 'g'];
const b = ['a', 'b'];
const c = ['a', 'e', 'f'];
arrayDiff(a, b, c); // (4) ["c", "d", "g", "f"]

Я хотел аналогичную функцию, которая взяла старый массив и новый массив и дала мне массив добавленных элементов и массив удаленных элементов, и я хотел, чтобы она была эффективной (так что нет .содержит!).

вы можете играть с моим предлагаемым решением здесь:http://jsbin.com/osewu3/12.

может ли кто-нибудь увидеть какие-либо проблемы/улучшения в этом алгоритме? Спасибо!

код:

function diff(o, n) {
  // deal with empty lists
  if (o == undefined) o = [];
  if (n == undefined) n = [];

  // sort both arrays (or this won't work)
  o.sort(); n.sort();

  // don't compare if either list is empty
  if (o.length == 0 || n.length == 0) return {added: n, removed: o};

  // declare temporary variables
  var op = 0; var np = 0;
  var a = []; var r = [];

  // compare arrays and add to add or remove lists
  while (op < o.length && np < n.length) {
      if (o[op] < n[np]) {
          // push to diff?
          r.push(o[op]);
          op++;
      }
      else if (o[op] > n[np]) {
          // push to diff?
          a.push(n[np]);
          np++;
      }
      else {
          op++;np++;
      }
  }

  // add remaining items
  if( np < n.length )
    a = a.concat(n.slice(np, n.length));
  if( op < o.length )
    r = r.concat(o.slice(op, o.length));

  return {added: a, removed: r}; 
}

Я искал простой ответ, который не включал использование разных библиотек, и я придумал свой собственный, который, я не думаю, был упомянут здесь. Я не знаю, насколько он эффективен или что-то еще, но он работает;

    function find_diff(arr1, arr2) {
      diff = [];
      joined = arr1.concat(arr2);
      for( i = 0; i <= joined.length; i++ ) {
        current = joined[i];
        if( joined.indexOf(current) == joined.lastIndexOf(current) ) {
          diff.push(current);
        }
      }
      return diff;
    }

для моего кода мне также нужны дубликаты, но я думаю, что это не всегда предпочтительно.

Я думаю, что основным недостатком является потенциальное сравнение многих вариантов, которые уже были отклонены.


в ответ на человека, который хотел вычесть один массив из другого...

если не более 1000 элементов, попробуйте это...

настройте новую переменную для дублирования Array01 и назовите ее Array03.

теперь используйте алгоритм сортировки пузырьков для сравнения элементов Array01 с Array02 и всякий раз, когда вы найдете совпадение выполните следующие действия, чтобы Array03...

 if (Array01[x]==Array02[y]) {Array03.splice(x,1);}

NB: мы модифицируем Array03 вместо Array01, чтобы не испортить вложенный петли типа пузырьков!

наконец, скопируйте содержимое Array03 в Array01 с помощью простого задания, и все готово.