Як знайти голку в копиці сіна?


74

Виконуючи пошук голки в копиці сіна об’єктно-орієнтованим способом, ви, по суті, маєте три альтернативи:

1. needle.find(haystack)

2. haystack.find(needle)

3. searcher.find(needle, haystack)

Кому ви віддаєте перевагу, і чому?

Я знаю, що деякі люди віддають перевагу другій альтернативі, оскільки вона уникає введення третього об’єкта. Однак я не можу не відчувати, що третій підхід є більш концептуально "правильним", принаймні, якщо ваша мета полягає в моделюванні "реального світу".

В яких випадках, на вашу думку, виправдано вводити допоміжні об’єкти, такі як шукач у цьому прикладі, і коли їх слід уникати?


1
+1 Гарний заголовок та хороша семантика. Більшість кожної мови OO вражає таку проблему (подумайте про string.joinметод Python ).
new123456

Відповіді:


53

Зазвичай дії слід застосовувати до того, над чим ви робите дію ... у цьому випадку до копиці сіна, тому я вважаю, що варіант 2 є найбільш підходящим.

У вас також є четверта альтернатива, яка, на мою думку, буде кращою, ніж альтернатива 3:

haystack.find(needle, searcher)

У цьому випадку це дозволяє вказати спосіб, у який ви хочете здійснити пошук як частину дії, і таким чином ви можете зберегти дію з об’єктом, який оперується.


1
Це схоже на шаблон стратегії ( en.wikipedia.org/wiki/Strategy_pattern )
ARKBAN

Це схоже на порушення Принципу єдиної відповідальності. Варіант №3, безумовно, є кращим вибором дизайну.
Kyle W. Cartmell

1
Насправді це більше схоже на шаблон відвідувача; безумовно, це його мається на увазі намір. "шукач" може бути будь-яким алгоритмом пошуку, метою якого є відвідувач. Звичайно, щось із "копиці сіна" повинно бути виставлене (HayCollection, я гадаю), щоб "шукач" міг шукати; але це не означає, що SRP порушується фактично або в дусі. en.wikipedia.org/wiki/Visitor_pattern .
radarbob

55

З трьох я віддаю перевагу варіанту №3.

Принцип єдиної відповідальності змушує мене не хотіти застосовувати можливості пошуку на своїх DTO або моделях. Їх відповідальність полягає в тому, щоб бути даними, а не знаходити себе, ні голки не повинні знати про копиці сіна, ні копиці сіна про голки.

Для того, що це варте, я думаю, що більшості практикуючих ООС потрібно довгий час, щоб зрозуміти, чому №3 є найкращим вибором. Я займався ОО протягом десятиліття, мабуть, ще до того, як по-справжньому прогриз.

@wilhelmtell, C ++ - одна з небагатьох мов зі спеціалізацією на шаблонах, які змушують таку систему насправді працювати. Для більшості мов метод "знайти" загального призначення був би ЖАХЛИВОЮ ідеєю.


16

Існує ще одна альтернатива, яка полягає у підході, що використовується STL для C ++:

find(haystack.begin(), haystack.end(), needle)

Я думаю, що це чудовий приклад того, що С ++ кричить "у твій обличчя!" до ООП. Ідея полягає в тому, що ООП - це не будь-яка срібна куля; іноді речі найкраще описувати з точки зору дій, іноді з точки зору предметів, іноді ні того, ні іншого, і того і іншого.

Б'ярн Страуструп сказав у TC ++ PL, що при розробці системи ви повинні прагнути відображати реальність, обмежуючись ефективним та дієвим кодом. Для мене це означає, що ви ніколи не повинні слідувати нічого сліпо. Подумайте про речі, що знаходяться під рукою (копиця сіна, голка) та контекст, в якому ми перебуваємо (пошук, це те, про що йдеться у вислові).

Якщо основна увага приділяється пошуку, то використовуйте алгоритм (дію), який підкреслює пошук (тобто гнучко підходить для копиць сіна, океанів, пустель, пов'язаних списків). Якщо основна увага приділяється копиці сіна, інкапсулюйте метод пошуку всередині об’єкту копиці сіна тощо.

Тим не менш, іноді ви сумніваєтесь і вам важко робити вибір. У цьому випадку будьте об’єктно-орієнтованими. Якщо ви передумаєте пізніше, я думаю, що простіше витягти дію з об’єкта, ніж розділити дію на об’єкти та класи.

Дотримуйтесь цих вказівок, і ваш код стане чіткішим і ну гарнішим.


15

Я б сказав, що варіант 1 повністю вийшов. Код слід читати таким чином, щоб підказувати вам, що він робить. Варіант 1 змушує мене думати, що ця голка збирається знайти мені копицю сіна.

Варіант 2 виглядає непогано, якщо стог сіна повинен містити голки. ListCollections завжди будуть містити ListItems, тому колекція.find (item) є природною та виразною.

Я думаю, що введення допоміжного об'єкта є відповідним, коли:

  1. Ви не контролюєте реалізацію відповідних об'єктів
    IE: search.find (ObsecureOSObject, файл)
  2. Не існує регулярних або розумних взаємозв'язків між об'єктами
    IE: nameMatcher.find (будинки, дерева.ім'я)

Ви можете скористатися иглою.findIn (копиця сіна). Ім'я змінної тут не проблема, це синтаксис.
sep332

11

Я з Бредом на цьому. Чим більше я працюю над надзвичайно складними системами, тим більше я бачу необхідність по-справжньому роз'єднати об'єкти. Він має рацію. Очевидно, що голка не повинна нічого знати про копицю сіна, тому 1 точно вийшов. Але копиця сіна нічого не повинна знати про голку.

Якби я моделював копицю сіна, я міг би застосувати її як колекцію - але як колекцію сіна чи соломи - а не колекцію голок! Однак я б взяв до уваги, що речі справді губляться в копиці сіна, але я нічого не знаю про те, що саме це. Я думаю, що краще не змушувати копицю сіна шукати речі самі по собі (наскільки розумною є копиця сіна). Правильний підхід до мене полягає в тому, щоб копиця сіна представляла колекцію речей, які знаходяться в ній, але не є соломою чи сіном або тим, що надає копиці сіна суть.

class Haystack : ISearchableThingsOnAFarm {
   ICollection<Hay> myHay;
   ICollection<IStuffSmallEnoughToBeLostInAHaystack> stuffLostInMe;

   public ICollection<Hay> Hay {
      get {
         return myHay;
      }
   }

   public ICollection<IStuffSmallEnoughToBeLostInAHayStack> LostAndFound {
      get {
        return stuffLostInMe;
      }
   }
}

class Needle : IStuffSmallEnoughToBeLostInAHaystack {
}

class Farmer {
  Search(Haystack haystack, 
                 IStuffSmallEnoughToBeLostInAHaystack itemToFind)
}

Насправді є більше того, що я збирався вводити та абстрагувати інтерфейси, а потім зрозумів, наскільки божевільним став я. Відчував, ніби я навчався в класі CS в коледжі ...: P

Ви зрозуміли ідею. Я думаю, що їхати якомога вільніше, це можливо - це добре, але, можливо, я трохи захопився! :)


6

Якщо і Needle, і копиця сіна є DAO, то про варіанти 1 і 2 мова не може йти.

Причиною цього є те, що DAO повинні нести відповідальність лише за зберігання властивостей об'єктів реального світу, які вони моделюють, і мати лише методи getter та setter (або просто прямий доступ до властивостей). Це полегшує написання серіалізації DAO у файл або створення методів для загального порівняння / загальної копії, оскільки код не міститиме цілу купу операторів if, щоб пропустити ці допоміжні методи.

Це лише залишає варіант 3, який більшість погодиться бути правильним.

Варіант 3 має кілька переваг, причому найбільшою перевагою є модульне тестування. Це пов’язано з тим, що і об’єкти Needle, і Haystack можна легко знущатись зараз, тоді як, якщо б використовувались варіанти 1 або 2, перед виконанням пошуку потрібно було б змінити внутрішній стан або Needle, або Haystack.

По-друге, завдяки тому, що шукач зараз знаходиться в окремому класі, весь код пошуку може міститися в одному місці, включаючи загальний код пошуку. Тоді як якщо код пошуку було введено в DAO, загальний код пошуку або зберігався б у складній ієрархії класів, або в будь-якому випадку в класі Spercher Helper.


5

Це цілком залежить від того, що змінюється, а що залишається незмінним.

Наприклад, я працюю над (не-ООП) фреймворком, де алгоритм пошуку різниться залежно від типу голки та копиці сіна. Окрім того, що для цього буде потрібно подвійне відправлення в об'єктно-орієнтованому середовищі, це також означає, що не має сенсу ні писати, ні needle.find(haystack)писати haystack.find(needle).

З іншого боку, ваша програма могла б із задоволенням делегувати знаходження одному з обох класів або взагалі дотримуватися одного алгоритму, і в цьому випадку рішення є довільним. У такому випадку я віддав би перевагу haystack.find(needle)способу, оскільки видається логічнішим застосувати знахідку до копиці сіна.


5

Виконуючи пошук голки в копиці сіна об’єктно-орієнтованим способом, ви, по суті, маєте три альтернативи:

  1. needle.find (копиця сіна)

  2. haystack.find (голка)

  3. searcher.find (голка, копиця сіна)

Кому ви віддаєте перевагу, і чому?

Виправте мене, якщо я помиляюся, але у всіх трьох прикладах у вас вже є посилання на голку, яку ви шукаєте, тож хіба це не схоже на пошук окулярів, коли вони сидять у вас на носі? : стор

Окрім каламбуру, я думаю, це насправді залежить від того, що ви вважаєте відповідальністю копиці сіна в межах даного домену. Ми просто дбаємо про це в тому сенсі, що є річчю, яка містить голки (по суті, колекція)? Тоді haystack.find (needlePredicate) добре. В іншому випадку, farmBoy.find (предикат, копиця сіна) може бути більш доречним.


needleможе бути типом. Але неоднозначність приводить до думки, що це може бути ситуація з куркою та яйцем.
new123456

4

Процитувавши великих авторів SICP ,

Програми повинні бути написані для читання людьми і лише випадково для запуску машин

Я вважаю за краще мати під рукою обидва методи 1 і 2. Використовуючи рубін як приклад, він поставляється з таким, .include?який використовується таким чином

haystack.include? needle
=> returns true if the haystack includes the needle

Іноді, я, суто з міркувань читабельності, хочу перевернути його. Ruby не постачається із in?методом, але це однокласник, тому я часто роблю таке:

needle.in? haystack
=> exactly the same as above

Якщо "важливіше" наголосити на копиці сіна чи операції пошуку, я вважаю за краще писати include?. Однак часто ані копиця сіна, ані пошук насправді не є тим, що вас турбує, а лише наявність об’єкта - у цьому випадку я вважаю, що це in?краще передає значення програми.


3

Це залежить від ваших вимог.

Наприклад, якщо ви не дбаєте про властивості шукача (наприклад, про силу шукача, зір тощо), то я б сказав, що haystack.find (голка) буде найчистішим рішенням.

Але якщо ви піклуєтесь про властивості шукача (або будь-які інші властивості з цього приводу), я б ввів інтерфейс ISearcher або в конструктор копиці сіна, або в функцію для полегшення цього. Це підтримує як об'єктно-орієнтоване проектування (копиця сіна має голки), так і інверсію управління / введення залежностей (полегшує модульне тестування функції "знайти").


3

Я можу думати про ситуації, коли будь-який із перших двох смаків має сенс:

  1. Якщо голка потребує попередньої обробки, як в алгоритмі Кнута-Моріса-Пратта, needle.findIn(haystack)(або pattern.findIn(text)) має сенс, оскільки об’єкт голки містить проміжні таблиці, створені для ефективної роботи алгоритму

  2. Якщо копиця сіна потребує попередньої обробки, як, скажімо, в триє, то haystack.find(needle)(або words.hasAWordWithPrefix(prefix)) працює краще.

В обох вищевказаних випадках один із голки чи копиці сіна знає про обшук. Крім того, вони обоє усвідомлюють одне одного. Якщо ви хочете, щоб голка та копиця сіна не знали один про одного або про пошук, searcher.find(needle, haystack)було б доречно.


2

Легко: спалити копицю сіна! Згодом залишиться лише голка. Крім того, ви можете спробувати магніти.

Складніше запитання: Як знайти одну конкретну голку в басейні голок?

Відповідь: накрутіть кожну нитку та прикріпіть інший кінець кожної нитки нитки до відсортованого індексу (тобто покажчиків)


2

Відповідь на це питання насправді повинен залежати від домену, для якого застосовується рішення.
Якщо вам вдається імітувати фізичний пошук у фізичному стозі сіна, ви можете мати класи

  • Космос
  • Солома
  • Голка
  • Шукач

Космос
знає, які об'єкти знаходяться, за якими координатами
реалізуються закони природи (перетворює енергію, виявляє зіткнення тощо)

Голка , Солома
знаходяться в просторі,
реагують на сили

Шукач
взаємодіє з простором:
    рухається рукою, застосовує магнітне поле, спалює сіно, застосовує рентген, шукає голку ...

Таким чином   seeker.find(needle, space)   або   seeker.find(needle, space, strategy)

Сінокос просто опиняється в просторі, де ви шукаєте голку. Коли ви абстрагуєте далекий простір як якусь віртуальну машину (згадайте: матрицю), ви можете отримати вищезазначене за допомогою копиці сіна, а не простору (рішення 3 / 3b) :

seeker.find(needle, haystack)     або     seeker.find(needle, haystack, strategy)

Але матрицею був Домен, який слід замінювати копицею сіна, лише якщо ваша голка не може бути ніде більше.

І знову ж таки, це була просто анологія. Цікаво, що це відкриває розум для абсолютно нових напрямків:
1. Чому ви спочатку розпустили голку? Чи можете ви змінити процес, щоб не втратити його?
2. Чи потрібно вам знайти загублену голку, чи можете просто отримати іншу і забути про першу? (Тоді було б непогано, якби голка через деякий час розчинилася)
3. Якщо ви регулярно втрачаєте голки і вам потрібно їх знову знаходити, тоді, можливо, вам захочеться

  • роблять голки, здатні знайти себе, наприклад, вони регулярно запитують себе: чи я загубився? Якщо відповідь позитивна, вони посилають комусь своє GPS-розраховане положення або починають подавати звуковий сигнал або що завгодно:
    needle.find(space)або needle.find(haystack)    (рішення 1)

  • встановіть копицю сіна з камерою на кожну соломинку, після чого ви можете запитати вулик копиці сіна, чи бачив він голку нещодавно:
    haystack.find (голка) (рішення 2)

  • прикріпіть RFID-мітки до своїх голок, щоб ви могли легко триангулювати їх

Це все лише для того, щоб сказати, що у вашій реалізації ви зробили голку і копицю сіна, і більшу частину часу матрицю на якомусь рівні.

Тож вирішіть відповідно до свого домену:

  • Це мета стосу, щоб містити голки? Потім перейдіть за рішенням 2.
  • Чи природно, що голка загубиться де завгодно? Тоді перейдіть за рішенням 1.
  • Голка випадково загубляється в копиці сіна? Тоді перейдіть до рішення 3. (або розгляньте іншу стратегію відновлення)

2

haystack.find (голка), але має бути поле пошуку.

Я знаю, що ін’єкція на залежність - це лють, тому мене не дивує, що haystack.find @Mike Stone прийнятий (голка, шукач). Але я не погоджуюся: вибір того, що шукач використовується, мені здається рішенням для копиці сіна.

Розглянемо два ISearchers: MagneticSearcher здійснює ітерацію над гучністю, переміщуючи та ступаючи магнітом у спосіб, відповідний силі магніту. QuickSortSearcher ділить стос на дві частини, доки голка не буде помітна в одному з субпілей. Правильний вибір шукача може залежати від того, наскільки велика копиця сіна (наприклад, щодо магнітного поля), як голка потрапила в копицю сіна (тобто, чи справді положення голки є випадковим, чи вона упереджена?) Тощо.

Якщо у вас є haystack.find (голка, шукач), ви говорите, що "вибір найкращої стратегії пошуку найкраще робити поза контекстом копиці сіна". Я не думаю, що це, мабуть, буде правильно. Я думаю, що більш імовірно, що «копиці сіна знають, як найкраще шукати себе». Додайте сеттер, і ви все одно можете вводити пошуковий засіб вручну, якщо вам потрібно замінити або для тестування.


1

Особисто мені подобається другий метод. Моє міркування полягає в тому, що основні API, з якими я працював, використовують цей підхід, і я вважаю, що це має найбільший сенс.

Якщо у вас є список речей (копиця сіна), ви б шукали (знаходили ()) голку.


1

@Peter Meyer

Ви зрозуміли ідею. Я думаю, що їхати якомога вільніше, це можливо - це добре, але, можливо, я трохи захопився! :)

Помиляйте ... так ... я думаю, що IStuffSmallEnoughToBeLostInAHaystackце червоний прапор :-)


1

У вас також є четверта альтернатива, яка, на мою думку, буде кращою, ніж альтернатива 3:

haystack.find(needle, searcher)

Я бачу вашу думку, але що, якщо searcherреалізує пошуковий інтерфейс, який дозволяє шукати інші типи об’єктів, крім копиць сіна, і знаходити в них інші речі, крім голок?

Інтерфейс також може бути реалізований з різними алгоритмами, наприклад:

binary_searcher.find(needle, haystack)
vision_searcher.find(pitchfork, haystack)
brute_force_searcher.find(money, wallet)

Але, як вже вказували інші, я також вважаю, що це корисно лише у тому випадку, якщо ви насправді маєте кілька алгоритмів пошуку або декілька класів, які можна шукати або знайти. Якщо ні, я погоджуюсь, що haystack.find(needle)це краще через його простоту, тому я готовий пожертвувати деякою "коректністю" заради цього.


1
class Haystack {//whatever
 };
class Needle {//whatever
 }:
class Searcher {
   virtual void find() = 0;
};

class HaystackSearcher::public Searcher {
public:
   HaystackSearcher(Haystack, object)
   virtual void find();
};

Haystack H;
Needle N;
HaystackSearcher HS(H, N);
HS.find();

1

Суміш 2 та 3, справді.

Деякі копиці сіна не мають спеціалізованої стратегії пошуку; прикладом цього є масив. Єдиний спосіб щось знайти - це почати спочатку і випробувати кожен предмет, поки не знайдете той, який ви хочете.

Для такого роду речей, мабуть, найкраща безкоштовна функція (як C ++).

Деякі копиці сіна можуть мати спеціальну стратегію пошуку. Масив можна сортувати, що дозволяє використовувати, наприклад, двійковий пошук. Безкоштовна функція (або пара вільних функцій, наприклад sort і binary_search) - це, мабуть, найкращий варіант.

Деякі копиці сіна мають інтегровану стратегію пошуку як частину їх реалізації; наприклад, асоціативні контейнери (хешовані або впорядковані набори та карти). У цьому випадку пошук є, мабуть, важливим методом пошуку, тому, ймовірно, це повинен бути метод, тобто haystack.find (голка).


1

копиця сіна може містити речі один тип речей - це голкошукач - це те, що відповідає за пошук речей, шукач може прийняти купу речовин як джерело, де шукати речі, шукач може також прийняти опис речі, яку йому потрібно знайти

тому, бажано, для гнучкого рішення ви зробите щось на зразок: інтерфейс IStuff

Сінокіс = IList <IStuff> Голка: IStuff

Finder .Знайдіть (IStuff stuffToLookFor, IList <IStuff> stuffsToLookIn)

У цьому випадку ваше рішення не буде прив’язане лише до голки та копиці сіна, але воно буде корисним для будь-якого типу, який реалізує інтерфейс

так що якщо ви хочете знайти рибу в океані, можете.

var results = Finder.Find (fish, ocean)


1

Якщо у вас є посилання на предмет голки, чому ви його шукаєте? :) Проблемний домен та варіанти використання говорять вам, що вам не потрібно точно розташувати голку в копиці сіна (наприклад, те, що ви можете отримати з list.indexOf (елемент)), вам просто потрібна голка. А у вас його ще немає. Тож моя відповідь приблизно така

Needle needle = (Needle)haystack.searchByName("needle");

або

Needle needle = (Needle)haystack.searchWithFilter(new Filter(){
    public boolean isWhatYouNeed(Object obj)
    {
        return obj instanceof Needle;
    }
});

або

Needle needle = (Needle)haystack.searchByPattern(Size.SMALL, 
                                                 Sharpness.SHARP, 
                                                 Material.METAL);

Я погоджуюсь, що існує більше можливих рішень, які базуються на різних стратегіях пошуку, тому вони запроваджують пошуковий запит. З цього приводу було достатньо коментарів, тому я не звертаю на це уваги. Я маю на увазі рішення вище, забудьте про варіанти використання - який сенс шукати щось, якщо у вас на це вже є посилання? У найбільш природному варіанті використання у вас ще немає голки, тому ви не використовуєте змінну голку.


1

Бред Вілсон зазначає, що предмети повинні нести єдину відповідальність. В крайньому випадку, об’єкт несе одну відповідальність і не має держави. Тоді це може стати ... функцією.

needle = findNeedleIn(haystack);

Або ви можете написати це так:

SynchronizedHaystackSearcherProxyFactory proxyFactory =
    SynchronizedHaystackSearcherProxyFactory.getInstance();
StrategyBasedHaystackSearcher searcher =
    new BasicStrategyBasedHaystackSearcher(
        NeedleSeekingStrategies.getMethodicalInstance());
SynchronizedHaystackSearcherProxy proxy =
    proxyFactory.createSynchronizedHaystackSearcherProxy(searcher);
SearchableHaystackAdapter searchableHaystack =
    new SearchableHaystackAdapter(haystack);
FindableSearchResultObject foundObject = null;
while (!HaystackSearcherUtil.isNeedleObject(foundObject)) {
    try {
        foundObject = proxy.find(searchableHaystack);
    } catch (GruesomeInjuryException exc) {
        returnPitchforkToShed();  // sigh, i hate it when this happens
        HaystackSearcherUtil.cleanUp(hay); // XXX fixme not really thread-safe,
                                           // but we can't just leave this mess
        HaystackSearcherUtil.cleanup(exc.getGruesomeMess()); // bug 510000884
        throw exc; // caller will catch this and get us to a hospital,
                   // if it's not already too late
    }
}
return (Needle) BarnyardObjectProtocolUtil.createSynchronizedFindableSearchResultObjectProxyAdapterUnwrapperForToolInterfaceName(SimpleToolInterfaces.NEEDLE_INTERFACE_NAME).adapt(foundObject.getAdaptable());

лямбда, остаточний
фасадний

1

Стог сіна не повинен знати про голку, а голка не повинна знати про копицю сіна. Той, хто шукає, повинен знати про обидва, але чи варто знати копицю сіна, як саме шукати, є справжньою суперечкою.

Тож я б пішов із поєднанням 2 і 3; копиця сіна повинна мати можливість повідомляти комусь іншому, як шукати її, а шукач повинен мати можливість використовувати цю інформацію для пошуку копиці сіна.



1

Код намагається знайти конкретну голку або просто будь-яку? Це звучить як дурне запитання, але це змінює проблему.

Шукаючи конкретну голку, код у питанні має сенс. Шукаючи будь-яку голку, це було б більше схоже

needle = haystack.findNeedle()

або

needle = searcher.findNeedle(haystack)

У будь-якому випадку, я вважаю за краще мати шукача цього класу. Стог сіна не знає, як шукати. З точки зору CS - це просто сховище даних з БАГАТОЮ лайною, якої вам не потрібно.


Це гарне запитання. Я припускаю, що ми хочемо знайти конкретну голку, тобто ту, яку ви загубили в копиці сіна. Якщо ви просто хотіли знайти будь-яку голку, магнітний підхід, запропонований раніше, також спрацював би
;;

0

Безумовно, третій, ІМХО.

Питання про голку в копиці сіна є прикладом спроби знайти один об’єкт у великій колекції інших, що вказує на те, що йому потрібен складний алгоритм пошуку (можливо, за участю магнітів або (що, швидше за все,) дочірніх процесів), і це не означає Немає сенсу в тому, що стог сіна повинен керувати потоками або здійснювати складні пошуки.

Об'єкт пошуку, однак, присвячений пошуку, і можна очікувати, що він знатиме, як керувати дочірніми потоками для швидкого двійкового пошуку, або використовувати властивості шуканого елемента, щоб звузити область (тобто: магніт для пошуку чорних предметів) .


0

Іншим можливим способом може бути створення двох інтерфейсів для об'єкта, який можна шукати, наприклад, копиці сіна та об'єкта ToBeSearched, наприклад голки. Отже, це можна зробити таким чином

public Interface IToBeSearched
{}

public Interface ISearchable
{

    public void Find(IToBeSearched a);

}

Class Needle Implements IToBeSearched
{}

Class Haystack Implements ISearchable
{

    public void Find(IToBeSearched needle)

   {

   //Here goes the original coding of find function

   }

}

0
haystack.iterator.findFirst(/* pass here a predicate returning
                               true if its argument is a needle that we want */)

iteratorможе бути інтерфейсом до будь-якої незмінної колекції, при цьому колекції мають спільний findFirst(fun: T => Boolean)метод. Поки копиця сіна незмінна, не потрібно приховувати будь-які корисні дані ззовні. І, звичайно, недобре пов’язувати реалізацію нестандартної нестандартної колекції та деяких інших речей, які є haystack. Розділяй і завойовуй, добре?


0

У більшості випадків я вважаю за краще мати можливість виконувати такі прості допоміжні операції над основним об’єктом, але залежно від мови, об’єкт, про який йде мова, може не мати достатнього або розумного методу.

Навіть у таких мовах, як JavaScript ), які дозволяють збільшувати / розширювати вбудовані об’єкти, я вважаю, що це може бути як зручно, так і проблематично (наприклад, якщо майбутня версія мови вводить більш ефективний метод, який замінюється спеціальним).

Ця стаття добре описує такі сценарії.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.