根据位置将数组中的元素相乘
Posted
技术标签:
【中文标题】根据位置将数组中的元素相乘【英文标题】:Multiply elements in an array according to their position 【发布时间】:2014-05-26 23:28:34 【问题描述】:我可以使用什么有效的函数来按位置增加数组中元素的数量?
例如,如果我有一个数组:
ARRAY[10,20,30,40,50]::INT[]
我希望它变成:
ARRAY[10,20,20,30,30,30,40,40,40,40,50,50,50,50,50]::INT[]
所以我有 1 个“10”、2 个“20”、3 个“30”、4 个“40”和 5 个“50”。
对于数组:
ARRAY[10,20,30,40,10]::INT[]
我希望它变成:
ARRAY[10,20,20,30,30,30,40,40,40,40,10,10,10,10,10]::INT[]
所以我有 6 个“10”、2 个“20”、3 个“30”和 4 个“40”。
【问题讨论】:
【参考方案1】:WITH t AS (SELECT ARRAY[10,20,30,40,50]::INT[] AS arr) -- variable for demo
SELECT ARRAY(
SELECT unnest(array_fill(arr[idx], ARRAY[idx])) AS mult
FROM (SELECT arr, generate_subscripts(arr, 1) AS idx FROM t) sub
);
我会将逻辑包装到一个简单的 IMMUTABLE SQL 函数中:
CREATE OR REPLACE FUNCTION f_expand_arr(_arr anyarray)
RETURNS anyarray AS
$func$
SELECT ARRAY(
SELECT unnest(array_fill(_arr[idx], ARRAY[idx]))
FROM (SELECT generate_subscripts(_arr, 1) AS idx) sub
)
$func$ LANGUAGE sql IMMUTABLE;
由于具有多态参数类型anyarray
:How to write a function that returns text or integer values?
generate_subscripts()
和 array_fill()
的手册。
注意:这适用于实际的数组索引,它可能与 Postgres 中的序数数组位置不同。您可能对@Daniel 的“标准化”数组索引的方法感兴趣:Normalize array subscripts for 1-dimensional array so they start with 1
即将推出的 Postgres 9.4(目前为测试版)提供 WITH ORDINALITY
:PostgreSQL unnest() with element number
允许这种更加优雅和可靠的解决方案:
CREATE OR REPLACE FUNCTION f_expand_arr(_arr anyarray)
RETURNS anyarray AS
$func$
SELECT ARRAY(
SELECT unnest(array_fill(a, ARRAY[idx]))
FROM unnest(_arr) WITH ORDINALITY AS x (a, idx)
)
$func$ LANGUAGE sql IMMUTABLE;
人们可能仍然认为正确的顺序实际上并没有保证。我声称它是...Parallel unnest() and sort order in PostgreSQL
呼叫:
SELECT f_expand_arr(ARRAY[10,20,30,40,10]::INT[]) AS a2;
或者对于表中的值:
SELECT f_expand_arr(a) AS a2 FROM t;
SQL Fiddle.
【讨论】:
以上是关于根据位置将数组中的元素相乘的主要内容,如果未能解决你的问题,请参考以下文章