2016-04-06 3 views
1

У меня есть три переменные, a, b и c. Каждая из этих переменных имеет свойство foo, которое является Boolean.Эффективный способ поиска элемента в массиве на основе его свойства?

Из a, b и c, ровно два из них имеют их собственность foo установлен true.

Что является самым эффективным способом узнать, какой из них установлен в false?

Чтобы поместить это в контекст, у меня есть функция, которую я хочу сделать некоторые вещи, на основании которых переменная имеет foo набор для false, и я не уверен, что это лучший способ пойти об определении того, что переменная false есть.

E.g. Я мог бы проверить вручную, используя, если такие заявления так:

function doThings():void 
    { 
     if (a.foo == true) 
     { 
      if (b.foo == true) 
      { 
       True = a; 
       True2 = b; 
       False = c; 
      } 
      else 
      { 
       True = a; 
       True2 = c; 
       False = b; 
      } 
     } 
     else 
     { 
      True = b; 
      True2 = c; 
      False = a; 
     } 

     //More things... 
    } 

Или иначе я думал о том, чтобы передать две переменные, которые я знаю, есть foo значение ИСТИНА в качестве аргументов функции, то сделать это:

function doThings(para, para2):void 
    { 
     if (a != para && a != para2) 
     { 
      False = a; 
     } 
     else if (b != para && b != para2) 
     { 
      False = b; 
     } 
     else 
     { 
      False = c; 
     } 

     //More things... 
    } 

Боковое примечание: два, которые имеют значение foo, равны true, являются push ed в массив во время выполнения, поэтому я не могу точно указать, какой из них программно, но я МОГУ передать их в качестве аргументов функции (ей).

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

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

function doThings():void 
    { 
     if (TrueArray.indexOf(a) == -1) 
     { 
      False = a; 
      True = b; 
      True2 = c; 
     } 
     else if (TrueArray.indexOf(b) == -1) 
     { 
      False = b; 
      True = c; 
      True2 = a; 
     } 
     else 
     { 
      False = c; 
      True = a; 
      True2 = b; 
     } 

     //More things... 
    } 

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

Спасибо за чтение.

ответ

1

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

function findFalseFoo(...objects:Array):Object { 
    for each (var object:Object in objects) { 
     if (object.foo == false) 
      return object; 
    } 
} 

function doStuff():void { 
    var falseFoo:Object = findFalseFoo(a, b, c); 
    switch (falseFoo) { 
     case a: 
      // do stuff 
      break; 
     case b: 
      // do stuff 
      break; 
     case c: 
      // do stuff 
      break; 
    } 
} 

Конечно, в коде Вы разместили все, что вы делаете в каждом конкретном случае установки False, True и True2 свойства. В таком случае вы могли бы просто сделать это:

function assignTrueFalse(...objects:Array):void { 
    False = True = True1 = null; 
    for each (var object:Object in objects) { 
     if (object.foo) { 
      if (True == null) 
       True = object; 
      else 
       True2 = object; 
     } else { 
      False = object; 
     } 
    } 
} 

assignTrueFalse(a, b, c); 
1

Если вам нужен только первый элемент массива с значением foo значения false, то наиболее эффективным способом, вероятно, будет простой цикл. Это также масштаб автоматически на любое количество элементов в массиве (вместо закодирован 3 шт)

//assumes you have an array of objects called 'myArray' 

function getFirstFalseFoo():Object { 
    //iterate over every item in 'myArray' 
    for(var i:int = 0, len:int = myArray.length; i < len; i++){ 
     //if the array item's foo value is false, return that object (thus exiting the loop) 
     if(!myArray[i].foo){ 
      return myArray[i]; 
     } 
    } 
} 

var myFalseFoo:Object = getFirstFalseFoo(); 


//OR, you could pass in objects as parameters to the function like this: 
function getFirstFalseFoo(... args):Object { 
    //iterate over every item passed to the function 
    for(var i:int = 0, len:int = args.length; i < len; i++){ 
     //if the item has a foo property and it's false, return that object (thus exiting the loop) 
     if(args[i].hasOwnProperty("foo") && !args[i].foo){ 
      return args[i]; 
     } 
    } 
} 

var myFalseFoo:Object = getFirstFalseFoo(a, b, c); //you could pass as many objects as you want 

Конечно, есть много способов сделать это и самый «эффективный» может зависеть от многих факторов и зависит от вашего определения эффективности (вычислительно быстрый, наименьший объем кода, наилучшая масштабируемость и т. д.).


Как в стороне, лучшая практика в AS3 (и во многих других языках), это есть имена переменные и функции начинаются с прописными буквами. Также лучше не указывать имена переменных для ключевых слов языка. Я бы рекомендовал изменив переменные на что-то вдоль этих линий, чтобы сделать его легче читать и понимать:

var falseObj:Object; 
var trueObj:Object; 
var true2Obj:Object; 
+0

Итак ... я должен удалить свой ответ сейчас, когда вы отредактировали весь код в своем ответе? :) – Aaron

+0

Забавно, я собирался сказать что-то, когда пришел ваш ответ. – BadFeelingAboutThis

+0

[Это редактирование] (http://stackoverflow.com/revisions/36457874/3) и [это править] (http://stackoverflow.com/revisions/36457874/4) после моего ответа с почти таким же кодом ... но что бы то ни было, возможно, просто совпадение, это, конечно, не новое решение. – Aaron

Смежные вопросы