AS3 Поиск общих значений в массивах - PullRequest
0 голосов
/ 13 декабря 2011

Я борюсь с чем-то, что не должно быть слишком сложным, но я не могу понять это. У меня есть несколько массивов с разными значениями, и я хочу найти общие значения, которые есть во всех массивах, см. Пример ниже.:

        var arrayOne:Array      = ["1","2","3"];
        var arrayTwo:Array      = ["1","2","7"];
        var arrayThree:Array    = ["1","2","9","12"];

        _resultArray = ["1","2"];

Любая помощь приветствуется.

Ответы [ 3 ]

3 голосов
/ 13 декабря 2011

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

var arrayOne : Array = [ "1", "2", "3" ];
var arrayTwo : Array = [ "1", "2", "7" ];
var arrayThree : Array = [ "1", "2", "9", "12" ];
// you can pass in any number of Arrays
trace ( searchArraysForCommonItems ( arrayOne, arrayTwo, arrayThree ) ); // returns ["1", "2"]


function searchArraysForCommonItems ( ...args : * ) : Array
{
    var searchArray : Array = [];
    for each ( var arr:Array in args)
        searchArray = searchArray.concat ( arr );

    var resultArray : Array = [];
    var last : String;
    var times : int = 0;
    for each ( var str : String in searchArray.sort ( Array.NUMERIC ))
        if (last == str) times++;
        else
        {
            if (times == args.length) resultArray.push ( last );
            last = str;
            times = 1;
        }

    return resultArray;
}

Конечно, вы можете (и должны) использовать Vector.<String> вместо Array везде, где это возможно, чтобы улучшить производительность, но всегда помните, что Array.sort() - встроенная функция и очень быстрая ...

3 голосов
/ 13 декабря 2011

Вы можете сделать что-то вроде:

///Returns common values between to arrays
function getCommonValues(array1:Array, array2:Array):Array
{
    var len1:int = array1.length;
    var len2:int = array2.length;
    var toReturn:Array = new Array();

    for(var i:int = 0; i < len1; i++){
        for(var n:int = 0; n < len2; n++){
            if(array1[i] == array2[n]){
                toReturn.push(array1[i]);
            }
        }
    }
    return toReturn;
}

Затем сделайте что-то вроде:

var arrayOneAndTwo:Array = getCommonValues(arrayOne,arrayTwo);
var _resultArray:Array = getCommonValues(arrayOneAndTwo,arrayThree);

При желании вы можете изменить функцию, включив в сравнение все три массива, что будет более эффективным.

Редактировать

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

///Returns common values between X number of sub arrays
function getCommonValuesFromSubArrays(papaArray:Array):Array
{
    if(papaArray.length < 2){ return papaArray; }

    var toReturn:Array = papaArray[0];

    for(var a:int = 1; a < papaArray.length; a++){
        toReturn = getCommonValues(toReturn, papaArray[a]);
    }

    return toReturn;
}

Тогда что-то вроде:

var arr1:Array = ["one","two","three","four","five"];
var arr2:Array = ["one","two","five","six"];
var arr3:Array = ["one","two","three","four","five"];
var arr4:Array = ["one","two","three","four","five"];

var bigOlArray:Array = [arr1,arr2,arr3,arr4];

var _results:Array = getCommonValuesFromSubArrays(bigOlArray);
2 голосов
/ 13 декабря 2011

Я бы использовал функцию Array.filter () для достижения этой цели:

var _resultArray:Array = arrayOne.filter(
   function(item:String, index:int, arr:Array):Boolean
   {
      return (arrayTwo.indexOf(item) != -1 && arrayThree.indexOf(item));
   }
);

Это зациклится над arrayOne и вернет массив со значениями, которые оба появятся также в arrayTwo и arrayThree.

Редактировать: А вот функция, которая будет принимать любое количество массивов и возвращать общие значения:

function getCommonValues(arrayOne:Array, ... arrays:Array):Array
{
    var _resultArray:Array = arrayOne.filter(
       function(item:String, index:int, arr:Array):Boolean
       {
          return arrays.every(
            function (a:Array, index2:int, arr2:Array):Boolean
            {
                return a.indexOf(item) != -1;
            }
          );
       }
    );
    return _resultArray;
}

Использование:

resultArray = getCommonValues(arrayOne, arrayTwo, arrayThree, arrayFour); 

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

...