количество против длины против размера в коллекции

167

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

Наиболее распространенными, кажется length, countи size.

например.

array.length
vector.size()
collection.count

Есть ли какой-либо предпочтительный термин для использования? Зависит ли это от типа коллекции? то есть. изменяемые / неизменны

Есть ли предпочтение, чтобы это было свойство вместо метода?

меласса
источник
И List.Capacityв C # есть свойство.
RBT
Я надеюсь, что новые языки будут избегать неоднозначных терминов.
Николай Климчук

Ответы:

231

Length() имеет тенденцию ссылаться на смежные элементы - например, строка имеет длину.

Count() имеет тенденцию ссылаться на количество элементов в более свободной коллекции.

Size() имеет тенденцию ссылаться на размер коллекции, часто это может отличаться от длины в таких случаях, как векторы (или строки), в строке может быть 10 символов, но память зарезервирована для 20. Это также может относиться к числу элементы - проверить источник / документацию.

Capacity()- используется для конкретной ссылки на выделенное пространство в коллекции, а не на количество допустимых элементов в ней. Если для типа определены и «емкость», и «размер», то «размер» обычно относится к числу фактических элементов.

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

gbjbaanb
источник
5
Так что же такое «более свободная коллекция»? Я не вижу разницы между размером и количеством здесь.
Софи Алперт
32
@ben: размер = доступные слоты, количество = фактические элементы. размер == считать, когда коллекция заполнена.
Стивен Эверс
8
Понижающее голосование потому, что size()относится к числу элементов в векторе, а не к его capacity()… по крайней мере в C ++, который, я думаю, является источником vectors с sizes.
Дейв Абрахамс
10
@DaveAbrahams - я никогда не говорил, что это так. Прочитайте это снова. Я сказал, что это «имеет тенденцию ссылаться», я даже не пытался сделать конкретное утверждение, которое в равной степени применимо ко всем перестановкам всех классов коллекций на всех языках.
gbjbaanb
2
@ SnOrfus Я думаю, что вы попали в сферу «возможностей» там. std::vector(C ++), например, использует «емкость» и «размер», где вы используете «размер» и «количество», соответственно. На самом деле, все в std::изезе «размере» для текущего счетчика элементов, даже std::string(что обеспечивает «размер» для совместимости шаблона и полностью идентичной «длиной» для ... человека удобства я думаю).
Джейсон C
28

FWIW (и это очень близко к нулю), я предпочитаю «Count», потому что он, кажется, указывает, что он собирается вернуть количество элементов / элементов в коллекции довольно однозначно.

Когда я сталкиваюсь с терминами «Длина» или «Размер», мне часто на мгновение задаётся вопрос (или даже заставляют перечитывать документацию), собирается ли эта чертова вещь сказать мне, сколько элементов в собрании или как много байтов, которые использует коллекция. Это особенно верно для коллекций, которые предназначены быть контингентными, как массивы или строки.

Но никто, кто отвечал за соглашения об именах, используемые стандартными инфраструктурами / библиотеками Java, BCL / .Net или C / C ++, не удосужился спросить меня, так что вы все застряли на том, что они придумали.

Если бы я был намного умнее меня и был назван Бьярне, все вы могли бы избавиться от страданий ...

Конечно, вернувшись в реальный мир, вы должны попытаться придерживаться любого соглашения об именах, используемого языком / платформой, которую вы используете (например, size()в C ++). Не то чтобы это, кажется, помогло вам Array.Lengthрешить вашу дилемму.

Майкл Берр
источник
16
Хотя Length и Size являются существительными, Count также является глаголом, поэтому его можно интерпретировать как подсчет во время выполнения (O (n)) против поиска значения (O (1)).
mbx
Действительно, именно так это и используется в LINQ: Enumerable.Count
Эдвард Брей,
11

Термины несколько взаимозаменяемы, хотя в некоторых ситуациях я бы предпочел одно другому. Обычно вы можете получить лучшее использование, если подумаете о том, как бы вы описали длину / размер / количество этого элемента в устной форме другому человеку?

length()подразумевает, что элемент имеет длину. Строка имеет длину. Вы говорите "строка длиной 20 символов", верно? Так что у него есть длина.

size()подразумевает, что элемент имеет размер. Например, файл имеет размер. Вы говорите "этот файл имеет размер 2 МБ", верно? Так что у него есть размер.

Тем не менее, строка также может иметь размер, но я бы ожидал чего-то другого здесь. Например, строка UTF-16 может иметь длину 100 символов, но, поскольку каждый символ состоит из двух байтов, я ожидаю, что размер будет 200.

count()очень необычно Objective-C использует количество для количества элементов в массиве. Можно спорить, если массив имеет длину (как в Java), имеет размер (как в большинстве других языков) или имеет счетчик. Тем не менее, размер может снова быть размером в байтах (если элементы массива 32-битные целые, каждый элемент имеет 4 байта) и длиной ... Я бы не сказал, что «массив состоит из 20 элементов», что звучит довольно странно для меня. Я бы сказал, что «массив состоит из 20 элементов». Я не уверен, выражает ли count это очень хорошо, но я думаю, что count здесь краткая форма, elementCount()и это опять же имеет гораздо больший смысл для массива, чем length () или size ().

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

Mecki
источник
Следуя вашей строковой аналогии, файл должен иметь length, но разные хранилища могут использовать разные sizesдля хранения своих данных. Java тоже так думает в java.io.File # length () , но похоже, что остальной мир не согласен.
Иван Балашов
1
@IvanBalashov Я никогда не использовал «длину файла» в ежедневных разговорах, для меня файл не имеет длины, кроме размера, и это также то, что я написал в своем ответе. Всякий раз, когда мы говорим о необработанных байтах, мы говорим о размере IMHO, а файл без какого-либо более близкого конкретного содержания - это просто набор байтов. Длина обычно используется не для выражения количества байтов, а для выражения накопления элементов, соединенных вместе (для меня байты не являются элементами, это скорее строительные блоки для формирования элементов, а также они не «соединены вместе»).
Меки
4

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

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

Корин
источник
3

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

Что касается свойства / метода, я бы использовал свойство, чтобы отметить его быстро, а метод, чтобы отметить его медленно.

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

Павел Капустин
источник
Так что насчет DataBlock, просто куча байтов. Он имеет длину или размер?
Меки
2

Добавление к ответу @ gbjbaanb ...

Если «свойство» подразумевает открытый доступ к значению, я бы сказал, что «метод» предпочтителен просто для обеспечения инкапсуляции и скрытия реализации.

Вы можете изменить свое мнение о том, как countэлементы или как вы поддерживаете это count. Если это свойство, вы застряли - если к нему обращаются через метод, вы можете изменить базовую реализацию, не влияя на пользователей коллекции.

Кен Джентл
источник
Почему вы "застряли", если он выставлен как собственность? Свойства имеют базовую реализацию, которая может изменяться так же легко, не нарушая интерфейс. Фактически, большинство языков реализуют свойства как сгенерированные компилятором методы get / set в любом случае ... вы просто не можете вызывать их напрямую.
Скотт Дорман
На какие "большинство языков" вы ссылаетесь? C, C ++, Java (просто назвать несколько) не делают этого. Руби и Groovy, я знаю, делают. Обратите внимание, как я начал ответ тоже: «Если« свойство »подразумевает ...» Почему застрял? Если интерфейс к классу меняется, клиенты должны измениться (вообще говоря)
Кен Джентл
1

В Elixir на самом деле существует четкая схема именования, связанная с разными типами языка.

При «подсчете» количества элементов в структуре данных Elixir также руководствуется простым правилом: функция называется по имени, sizeесли операция выполняется в постоянное время (т. Е. Значение предварительно рассчитано) или lengthесли операция является линейной (т. Е. Вычислением). длина становится медленнее по мере роста ввода).

brightball
источник
0

Для меня это немного похоже на вопрос, лучше ли «foreach», чем «для каждого». Это зависит только от языка / структуры.

EBGreen
источник
И какое это имеет значение? Какие изменения? Собираемся ли мы писать сердитые электронные письма людям Java, чтобы они выбрали два и были непоследовательны?
S.Lott
1
Это моя точка зрения. Почему интересно, что лучше. Что есть, то есть.
EBGreen
0

Я бы сказал, что это зависит от конкретного языка, который вы используете, и классов . Например, в c #, если вы используете Array, у вас есть свойство Length, если у вас есть что-то, что наследует от IEnumerable, у вас есть расширение метода Count (), но оно не быстрое. И если вы унаследовали от ICollection, у вас есть Property Count.

Александр
источник