2014-10-02 39 views
2

在许多其他语言,来压缩部分的清单一起指取像如何将多个单元格阵列压缩在一起?

((x1, x2, x3, x4), (y1, y2, y3, y3)) 

,并把它变成

((x1, y1), (x2, y2), (x3, y3), (x4, y4)) 

这当然可以推广到列表

  • 与超过2个子列表,
  • 其子列表不是长度为4,
  • 其子列表可能有完全不同的长度。

我发现自己做了很多,所以我想我会分享这个解决方案。

+0

很高兴看到那么现在一个有趣的Matlab的问题,然后:-) – 2014-10-02 21:18:15

+0

@LuisMendo:是的,这让我想起了一个老问题的这样做'cell2mat'与填充:http://stackoverflow.com/questions/3054437/how-can-i-accumulate-cells-of-different-lengths-in-a-matrix-in-matlab – Amro 2014-10-02 22:25:08

回答

2

这是我的实现:

function out = zipCells(varargin) 
    % make sure all inputs are cell arrays 
    assert(all(cellfun(@iscell, varargin)), 'Expecting cell arrays'); 

    % make them all of the same length 
    mn = min(cellfun(@numel, varargin)); 
    in = cellfun(@(c) c(1:mn), varargin, 'UniformOutput',false); 

    % zip lists 
    out = cellfun(@(varargin) varargin, in{:}, 'UniformOutput',false); 
end 

(最后一行使用comma-separated lists扩大单元阵列in{:}的单元阵列)

实施例:

>> c = zipCells({'x','y','z'}, {1,2}, {'a','b','c'}) 
c = 
    {1x3 cell} {1x3 cell} 
>> c{:} 
ans = 
    'x' [1] 'a' 
ans = 
    'y' [2] 'b' 
+0

+1 - 尼斯和干净的实施。 – rayryeng 2014-10-02 18:18:55

+0

+1 for generality – 2014-10-02 21:20:19

0

当然你也可以瓒一切在一起,但它们的名称应该有助于描述发生了什么:

function output = zipCells(varargin) 

numComponents = min(cellfun(@length, varargin)); 
makeComponentI = @(i) cellfun(@(c) c{i}, varargin, 'UniformOutput', false); 
output = arrayfun(makeComponentI, 1:numComponents, 'UniformOutput', false); 

这是它在行动:

>> pairs = zipCells({'a' 'b' 'c' 'd'}, {1 2 3 4}) 
pairs = 
    {1x2 cell} {1x2 cell} {1x2 cell} {1x2 cell} 
>> pairs{:} 
ans = 
    'a' [1] 
ans = 
    'b' [2] 
ans = 
    'c' [3] 
ans = 
    'd' [4] 

希望这有助于。

+0

当时限已过时,考虑接受你向StackOverflow社区发出的信号不再需要任何帮助。 – rayryeng 2014-10-02 18:18:24

1
  1. 如果所有单元具有相同的长度,有一个简单的解决方案没有cellfun,arrayfun或循环。它是基于这样的事实:mat2cell(其名称inspite)可以被施加到单元阵列:

    function out = zipCells(varargin) 
    n = numel(varargin{1}); 
    out = mat2cell(reshape([varargin{:}], n, []), ones(1, n)).'; 
    
  2. 一般情况下:修剪单元为最小长度(cellfun两种用途),并继续如上:

    function out = zipCells(varargin) 
    n = min(cellfun(@numel, varargin)); 
    varargin = cellfun(@(c) c(1:n), varargin, 'uniformoutput', 0); 
    out = mat2cell(reshape([varargin{:}], n, []), ones(1, n)).'; 
    
  3. 延伸以允许输入单元具有不同取向(行/列):

    function out = zipCells(varargin) 
    n = min(cellfun(@numel, varargin)); 
    varargin = cellfun(@(c) reshape(c(1:n), 1,[]), varargin, 'uniformoutput', 0); 
    out = mat2cell(reshape([varargin{:}], n, []), ones(1, n)).'; 
    
+0

'num2cell(。,2)'也可用于简化'mat2cell(。,ones(1,n))'调用 – Amro 2014-10-02 22:22:13

+0

@Amro奇怪这些函数的名字并不能反映它们的全部可以做。我猜他们的功能已经扩展了,但名字被保留了下来 – 2014-10-02 22:27:52

相关问题