根据位置将数组中的元素相乘

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?

,因此适用于 any 基本类型的数组

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.

【讨论】:

以上是关于根据位置将数组中的元素相乘的主要内容,如果未能解决你的问题,请参考以下文章

c# 使用 system.numerics 将数组元素相乘

numpy数组矩阵相乘的多种方式

如何使用JavaScript将循环内数组中的所有项目相乘[重复]

有效地将数组的(n-1)个元素相乘

将 2D NumPy 数组元素相乘并求和

如何将两个数组与每个元素相乘作为数字c ++