Как перебирать элементы хеша в среде R? - PullRequest
8 голосов
/ 14 сентября 2011

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

1

2

Но вместо этого я получаю две строки NULL, как я могу получить то, что хочу?

map <- new.env(hash=T, parent=emptyenv())
assign('a', 1, map)
assign('b', 2, map)
for (v in ls(map)) {
    print(map$v)
}

Ответы [ 2 ]

11 голосов
/ 14 сентября 2011

Использование «$» внутри функции, где требуется интерпретировать ввод, является распространенным источником ошибки программирования.Вместо этого используйте объект формы [[value]] (без кавычек.)

for (v in ls(map)) {
    print(map[[v]])
}
7 голосов
/ 14 сентября 2011

Это зависит от того, что вы хотите сделать.Я предполагаю, что ваш print пример выше - это то, что вы делаете просто в качестве примера, но вы можете захотеть сделать что-то большее, чем просто печать!

Если вы хотите получить объект на основе каждого элементасреды, то вы используете eapply(env, function).Он работает как другие функции *apply().Он возвращает список, чьи объекты являются объектами, которые вы создали из функции, переданной в eapply(), и чьи имена скопированы из среды.

Например, в вашем конкретном случае

map <- new.env(hash=T, parent=emptyenv())  
assign('a', 1, map)  
assign('b', 2, map)  

eapply(map, identity)

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

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

eapply(map, function(e) {
  # e here stands for a copy of an element of the environment
  e <- my.function(e)
  my.other.function(e)
})

Если вместо этого вы хотите сделать что-то для каждого из элементов среды, не возвращая объект списка в конце,вам следует использовать цикл for, как это сделал @DWin в своем ответе.

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

...