2013-02-28 5 views
4

Есть ли краткое обозначение для доступа к последнему элементу массива, аналогичному std :: vector :: back() в C++? Должен ли я писать:Краткая нотация для последнего элемента массива

veryLongArrayName.[veryLongArrayName.Length-1] 

каждый раз?

+4

Вы можете сделать 'Seq.last veryLongArrayName', но он не будет нигде не столь эффективным. Почему бы просто не написать встроенную функцию для этого один раз и вызвать _that_ каждый раз? – ildjarn

+0

@ildjarn Смешная вещь, я просто перечитывал свой вопрос, и я подумал о том же ответе. Единственным недостатком является создание субъективного языкового диалекта: некоторые люди будут использовать «назад», другие могут лучше «последним» и т. Д. –

+1

'Seq.last' уже устанавливает прецедент здесь; 'back' - это C++-ism, в основном из-за необходимости стандартной библиотеки различать итераторы и значения (т. е.' end' vs. 'back'). – ildjarn

ответ

10

Расширение от комментариев

Встроенная опция Seq.last veryLongArrayName, но учтите, что это O (N), а не O (1), так что для всех, кроме самых маленьких массивов, вероятно, слишком неэффективно для практического использования ,

Это говорит, что нет никакого вреда в абстрагирования этой функциональности себя:

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] 
[<RequireQualifiedAccess>] 
module Array = 
    let inline last (arr:_[]) = arr.[arr.Length - 1] 

Теперь вы можете сделать Array.last veryLongArrayName без дополнительных затрат вообще, сохраняя при этом код очень идиоматических и читаемым.

+0

Отлично! Я скопирую и вставляю его в сумку полезного файла трюков. Я только что начал с F # несколько дней назад, так что мне понадобится еще пару дней, чтобы узнать, что означают эти атрибуты. –

+0

@Paul: атрибуты не являются строго необходимыми, я просто добавил их, потому что у них есть встроенный модуль F # 'Array'. По сути, первый атрибут заставляет модуль 'Array' быть назван' ArrayModule' в IL (т. Е. Так будут отображаться другие языки, если он является общедоступным), а второй атрибут запрещает делать 'open Array'. – ildjarn

6

В качестве альтернативы написания функции для _ [], вы можете также написать свойство расширения для IList < «T>:

open System.Collections.Generic 

[<AutoOpen>] 
module IListExtensions = 
    type IList<'T> with 
     member self.Last = self.[self.Count - 1] 

let lastValue = [|1; 5; 13|].Last // 13 
5

Я не могу найти его в официальных документах, но F # 4 кажется, Array.last реализована из коробки:

/// Returns the last element of the array. 
/// array: The input array. 
val inline last : array:'T [] -> 'T 

Link to implementation at github.

+0

Спасибо, что сообщили мне. Я думаю, что это полезное дополнение к ядру F #. –

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