Arrays Postgres array_replace()函数来替换子数组

Arrays Postgres array_replace()函数来替换子数组,arrays,postgresql,replace,Arrays,Postgresql,Replace,postgres函数array\u replace(anyarray,anyelement,anyelement)在需要替换数组中的单个元素时非常有用 但是我需要用另一个序列替换数组中的一个元素序列。我希望能够有这样一个函数:array\u replace(anyarray,anyarray,anyarray) 比如说。如果我有这个数组:[A,B,C,D,E,F] 我想把它改成[A,1,2,3,d,E,F] 通过调用如下函数:array_replace([a,B,C,D,E,F],[B,C],[

postgres函数
array\u replace(anyarray,anyelement,anyelement)
在需要替换数组中的单个元素时非常有用

但是我需要用另一个序列替换数组中的一个元素序列。我希望能够有这样一个函数:
array\u replace(anyarray,anyarray,anyarray)

比如说。如果我有这个数组:
[A,B,C,D,E,F]

我想把它改成
[A,1,2,3,d,E,F]

通过调用如下函数:
array_replace([a,B,C,D,E,F],[B,C],[1,2,3])

要替换的元素都应该按照传递给函数的确切顺序依次传递。因此,以下调用不会改变原始数组,因为B和C不靠近原始数组的元素:

array_replace([A,B,X,C,D,E,F],[B,C],[1,2,3])


如何创建这样一个函数?

听起来您想要的是数组上的regexp\u替换。Postgres允许将数组转换为字符串(反之亦然)。然而,诀窍是将每个数组元素视为一个单词,并在等效的单词边界上进行匹配

下面的代码返回
{A,1,2,3,D,E,F}

Select array(
    select regexp_replace(
          (select array_to_string(array['A','B','C','D','E','F'],', ')),
          (select ' ' || array_to_string(array['B','C']),', ')),
          (select array_to_string(array[1,2,3],',')),
          'g'))))

(我确信有一种方法可以通过位置索引和创建函数等实现这一点,但这是我的快速解决方案)。

函数可能如下所示:

create or replace function array_replace_array(anyarray, anyarray, anyarray)
returns anyarray language plpgsql as $$
declare
    l1 int = array_length($1, 1);
    l2 int = array_length($2, 1);
    i int;
begin
    for i in 1 .. l1- l2+ 1 loop
        if $1[i : i+ l2- 1] = $2 then
            return $1[1 : i- 1] || $3 || $1[i+ l2 : l1];
        end if;
    end loop;
    return $1;
end $$;
示例:

select 
    array_replace_array('{A,B,C,D,E}'::text[], '{B,C}', '{X,Y,Z}') as "AXYZDE",
    array_replace_array('{A,B,C,D,E}'::text[], '{B,B}', '{X,Y,Z}') as "ABCDE",
    array_replace_array('{A,B,C,D,E}'::text[], '{A,B,C,D,E}', '{X,Y,Z}') as "XYZ",
    array_replace_array('{1,2,3,4}'::int[], '{2,3}', '{3,2}') as "1324";

    AXYZDE     |    ABCDE    |   XYZ   |   1324    
---------------+-------------+---------+-----------
 {A,X,Y,Z,D,E} | {A,B,C,D,E} | {X,Y,Z} | {1,3,2,4}
(1 row)

这是一个很好的解决方案,但由于您处理的是字符串,因此可能会替换部分字符串,而不是数组元素的整个值。此函数不适用于以下输入:
array_replace([1,12,3,4,5,6]、[2,3]、[17,18,19])。secon元素将成为117。伟大的点;我编辑了它来修改字符串的间距。。。更新后的正则表达式现在尝试尊重单词边界。我已经用你的例子测试过了,第二个元素没有变成117。