Применить purrr :: map к последовательности элементов вложенного списка [duplicate]

Есть несколько веских причин использовать статические методы:

  • Производительность: если вы хотите, чтобы какой-то код запускался, и вы не хотите создавать экземпляр дополнительного объекта, сделайте это в статический метод. JVM также может много оптимизировать статические методы (я думаю, что однажды я прочитал Джеймса Гослинга, заявив, что вам не нужны специальные инструкции в JVM, поскольку статические методы будут такими же быстрыми, но не могут найти источник - таким образом это может быть полностью ложным). Да, это микро-оптимизация и, вероятно, ненужная.
  • Практичность: вместо вызова new Util().method(arg) вызовите Util.method(arg) или method(arg) со статическим импортом.
  • Добавление методов: вы действительно хотели, чтобы класс String имел метод экземпляра removeSpecialChars(), но его нет (и этого не должно быть, так как специальные символы вашего проекта могут отличаться от другой проект), и вы не можете его добавить (поскольку Java является довольно разумным), поэтому вы создаете класс утилиты и вызываете removeSpecialChars(s) вместо s.removeSpecialChars(). Sweet.
  • Purity: принимая некоторые меры предосторожности, ваш статический метод будет чистой функцией , то есть единственное, от чего он зависит, - это его параметры. Данные, данные. Это легче читать и отлаживать, так как у вас нет наследования для наследования, о которых нужно беспокоиться. Вы можете сделать это также с помощью методов экземпляра, но компилятор поможет вам немного больше со статическими методами (не позволяя ссылаться на атрибуты экземпляра, переопределять методы и т. Д.).

Также нужно создать статический метод, если вы хотите сделать одноэлементный, но ... нет. Я имею в виду, подумайте дважды.

Теперь, что более важно, , почему вы не хотели бы создавать статический метод? В принципе, полиморфизм выходит из окна. Вы не сможете переопределить этот метод и не объявить его в интерфейсе (pre-Java 8) . Это требует большой гибкости от вашего дизайна. Кроме того, если вам нужно состояние, у вас будет много ошибок параллелизма и / или узких мест, если вы не будете осторожны.

15
задан Matthew Lundberg 23 April 2013 в 22:25
поделиться

5 ответов

16
ответ дан Victor K. 18 August 2018 в 15:06
поделиться

Теперь пакет purrr делает этот процесс очень простым:

library(purrr)

before %>% transpose()

## $x
## $x$a
##   a x
## 1 1 2
## 
## $x$b
##   b w
## 1 5 6
## 
## 
## $y
## $y$a
##   a y
## 1 3 4
## 
## $y$b
##   b z
## 1 7 8
5
ответ дан alistaire 18 August 2018 в 15:06
поделиться

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

invertList = function(l){
  elemnames = NULL
  for (i in seq_along(l)){
    elemnames = c(elemnames, names(l[[i]]))
  }

  elemnames = unique(elemnames)

  res = list()
  for (i in seq_along(elemnames)){
    res[[elemnames[i]]] = list()
    for (j in seq_along(l)){
      if(exists(elemnames[i], l[[j]], inherits = F)){
        res[[i]][[names(l)[j]]] = l[[names(l)[j]]][[elemnames[i]]]
      }
    }
  }
  res
}
1
ответ дан Chechy Levas 18 August 2018 в 15:06
поделиться

Вот другая идея - используйте тот факт, что data.table может хранить data.frame (на самом деле, учитывая ваш вопрос, возможно, вам даже не нужно работать со списками списков и может просто работать с data.table]:

library(data.table)

dt = as.data.table(before)
after = as.list(data.table(t(dt)))
4
ответ дан eddi 18 August 2018 в 15:06
поделиться
  • 1
    Это интересный подход. Я провел некоторое расследование data.table, но не использовал его почти достаточно. – Matthew Lundberg 23 April 2013 в 23:30
  • 2
    Это фактически не требует данных. Таблица as.list(data.frame(do.call(rbind, before))) также будет работать. – mnel 24 April 2013 в 02:18

Хотя это старый вопрос, я нашел его при поиске той же проблемы, и второй удар по google имел гораздо более элегантное решение, на мой взгляд:

list_of_lists <- list(a=list(x="ax", y="ay"), b=list(w="bw", z="bz"))
new <- do.call(rbind, list_of_lists) 

new теперь представляет собой прямоугольную структуру, странный объект: список с атрибутом измерения. Он работает с как можно большим количеством элементов, если каждый подсписчик имеет одинаковую длину. Чтобы изменить его на более общий R-объект, можно было бы, например, создать такую ​​матрицу:

new.dims <- dim(new)
matrix(new,nrow = new.dims[1])

new.dims необходимо было сохранить, так как функция matrix() удаляет атрибут список. Другой способ:

new <- do.call(c, new) 
dim(new) <- new.dims

Теперь вы можете, например, преобразовать его в data.frame с помощью as.data.frame() и разделить его на столбцы или выполнить операции с колониальной разметкой. Прежде чем вы это сделаете, вы также можете изменить атрибут dim матрицы, если он лучше подходит вашим потребностям.

3
ответ дан zerweck 18 August 2018 в 15:06
поделиться
  • 1
    Кроме того, это дает обманчивые результаты. Все матричные элементы являются списками – Rich Scriven 5 October 2015 в 22:11
  • 2
    Хм, не совсем, но похоже. Результатом является список из 4 отдельных символьных элементов (истинные матрицы могут содержать только атомные типы) с атрибутом измерения. Но в зависимости от варианта использования это не так уж плохо, его просто нужно преобразовать в "true" матрица. Я отредактирую свое решение, чтобы это отразить. – zerweck 6 October 2015 в 16:47
  • 3
    rbind в списке списков - прочная идея. – Neal Fultz 28 October 2017 в 20:08
Другие вопросы по тегам:

Похожие вопросы: