R:交换两个变量而不使用第三个变量

时间:2015-09-15 12:10:44

标签: r

我有两个变量(即):

git blame <filename>

我想换掉他们的价值观。是否有内置的R功能,能够执行该操作?或者是否有其他优雅的方式,而不使用第三个(临时)变量?

注意:如果可能适用于字符串或其他数据类型。

7 个答案:

答案 0 :(得分:8)

有一般解决方案或'技巧':

a <- 1
b <- 2

a <- a + b
b <- a - b
a <- a - b

这是一个有用的链接,解释了很多:xor-trick

答案 1 :(得分:7)

对于整数,您可以使用

a = a + b
b = a - b
a = a - b

对于字符串,这将起作用

a <- "one"
b <- "two"
a <- paste(a,b, sep = "")
b <- substr(a,0,nchar(a) - nchar(b))
a <- substr(a,nchar(b) + 1, nchar(a))

> a
# two
> b 
# one

答案 2 :(得分:2)

开始

A = 9
B = 5
A = A + B   

然后

A is 14
B is 5
B = A - B

然后

A is 14
B is 9
A = A - B 

结果:

A(5)现在是B

B(9)现在是A

不是很简单,只是使用第三个变量,但我的作品!

答案 3 :(得分:1)

在基础软件包中使用方式太多函数是件好事:总是有办法做某事,即使这是个坏主意。

list2env(list(a = b, b = a), envir = .GlobalEnv)

无论ab的类别是什么,这都有效。但我再说一遍:这是一个坏主意。

答案 4 :(得分:0)

虽然以前的答案都很精致漂亮,但它们都占据了我喜欢的太多空间!

所以我在C中提出了一个更整洁的解决方案:

a = (b - a) + (b = a);

它不适用于字符串,但整数和浮点都可以正常工作。

它的工作原理如下:

int a = 5, b = 7;
a = (b - a) + (b = a);
/* turns into */
a = (7 - 5) + (b = 5);
/* b is now 5 */
a = 2 + 5;
/* a is now 7 */

这里的关键是解析表达式的顺序(从左到右)。因此,表达式中第一次出现的 b b 的原始值替换,只有在此之后 b 被分配给

我意识到这是一个陈旧且已经回答的问题,但也许这对那里的人有用

答案 5 :(得分:0)

据我所知,没有内置函数来执行此操作,并且没有通用的方法可以在没有第三个变量的情况下交换两个变量。

但是,如果您正在使用至少可以减少代码重复的函数,则以下内容可能有所帮助:

swap <- function(x,y) {
  eval( parse( text = paste(
    "swap_unique_var_a<-", substitute(x), ";",
    substitute(x), "<-", substitute(y), ";",
    substitute(y), "<-swap_unique_var_a") ), env=parent.frame() )
}

然后您可以按如下方式使用它:

a<-1; b<-2;
swap(a,b)
print(a); print(b)

函数swap()的两个参数引用本地框架中的两个变量,然后交换创建临时文件以便这样做。

swap()功能的当前限制/问题:

  • 临时是在parent.frame()中创建的,您可以从swap()拨打x
  • 假设参数yparent.frame()位于parent.frame()环境中,因此在import urllib.request urllib.request.urlretrieve('ftp://abcxyz@abcxyz/foo', '20170622111600.csv') 环境中重新创建全局环境中的变量。

有可能使功能更加健壮,但我有点担心对性能的影响,特别是在R等解释性语言中,没有相当于内联的功能。

如果有兴趣/时间,我将测试性能并查看是否可以使用更强大的版本。

答案 6 :(得分:0)

更新Nathan的帖子:

list2env(list(x=y, y=x), envir=as.environment(environment()))