多个数组,每个有多个元素,彼此两两结合,怎么写比较优雅? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Luckyray
V2EX    程序员

多个数组,每个有多个元素,彼此两两结合,怎么写比较优雅?

  •  
  •   Luckyray 2018-05-15 15:56:54 +08:00 5089 次点击
    这是一个创建于 2710 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我想写接口的单元测试,每个参数都给了几个测试数据,不知道该怎么写了,想问问大家除了 N 个 for 循环还有什么办法?

    最好不是脚本语言的奇技淫巧...Java 没辣么灵活。
    24 条回复    2019-07-06 21:31:00 +08:00
    agagega
        1
    agagega  
       2018-05-15 16:16:24 +08:00   1
    你想实现的操作,如果我没有理解错的话,在脚本语言或者函数式语言里叫做 zip。

    [1, 2, 3, 4].zip([5, 6, 7, 8])
    # => [[1, 5], [2, 6], [3, 7], [4, 8]]

    Java 的话,可以看看 StackOverflow#3833814
    Luckyray
        2
    Luckyray  
    OP
       2018-05-15 16:38:43 +08:00
    @agagega 不太一样,我的意思不知道是不是应该叫“全结合”,就是排列组合里面的组合,15,16,17,18,25,26...这样,4*4 应该是 16 个结果。
    YenvY
        3
    YenvY  
       2018-05-15 16:41:12 +08:00
    看手写循环说的大概是排列组合?
    function test(arys, states) {
    if (arys.length) {

    arys.forEach(
    YenvY
        4
    YenvY  
       2018-05-15 16:49:02 +08:00   1
    function test(arys, states) {
    if (arys.length) {
    for (const elmt of arys[0]) {
    states.push(elmt);
    test(arys.slice(1), states)
    }
    states.pop();
    }
    else {
    console.log(states);
    states.pop();
    }
    }
    pinger
        5
    pinger  
       2018-05-15 17:02:36 +08:00
    function biu() {
    return Array.prototype.reduce.call(arguments, function(i, j) {
    var result = [];
    a.forEach(function(i) {
    b.forEach(function(j) {
    result.push(i.concat([j]))
    })
    });
    return result;
    }, [[]])
    }

    biu([1,2,3],[4,5,6],[7,8,9])
    pinger
        6
    pinger      2018-05-15 17:06:00 +08:00   1
    function biu() {
    return Array.prototype.reduce.call(arguments, function(a, b) {
    var result = [];
    a.forEach(function(a) {
    b.forEach(function(b) {
    result.push(a.concat([b]))
    })
    });
    return result;
    }, [[]])
    }

    biu([1,2,3],[4,5,6],[7,8,9])
    重发一次
    ycz0926
        7
    ycz0926  
       2018-05-15 17:06:59 +08:00
    $ zip [1..10] [20..30]
    [(1,20) ...]
    marcong95
        8
    marcong95  
       2018-05-15 17:11:29 +08:00   2
    笛卡尔积?
    CRVV
        9
    CRVV  
       2018-05-15 17:27:43 +08:00
    >>> a = [1, 2, 3, 4]
    >>> b = [5, 6, 7, 8]
    >>> [(x, y) for x in a for y in b]
    [(1, 5), (1, 6), (1, 7), (1, 8), (2, 5), (2, 6), (2, 7), (2, 8), (3, 5), (3, 6), (3, 7), (3, 8), (4, 5), (4, 6), (4, 7), (4, 8)]

    Python 和 Haskell 的正常写法,算不上奇技淫巧吧
    Java 的正常写法当然就是嵌套循环,我觉得足够优雅了
    covering
        10
    covering  
       2018-05-15 17:59:15 +08:00
    lz 是想要一个 generator 吧?

    class XG{public X next();}

    while (XG.next() != null) { test(X)}
    Luckyray
        11
    Luckyray  
    OP
       2018-05-15 17:59:35 +08:00
    @marcong95 对对,数学没学好话都说不清楚...
    RicardoScofileld
        12
    RicardoScofileld  
       2018-05-15 18:33:11 +08:00
    拿 numpy 或 pandas 处理一下?
    RicardoScofileld
        13
    RicardoScofileld  
       2018-05-15 18:34:24 +08:00
    不过我记得 collections 里面有一个方法可以实现,叫 com*什么来着想不起来了
    Semesse
        14
    Semesse  
       2018-05-15 18:58:06 +08:00 via Android
    python 的 itertools 就有 product
    gihnius
        15
    gihnius  
       2018-05-15 18:58:33 +08:00 via iPhone   1
    Ruby:

    a.product(b)
    3pmtea
        16
    3pmtea  
       2018-05-15 19:12:38 +08:00
    既然是 Java,那就 N 个 for 就完事儿了

    如果你想搞什么骚操作的话,有这么个思路:
    设计一个类,表示 N 位、size-进制的数,就可以只用一个 for,遍历这个对象的值域,达到枚举的目的
    mengyaoss77
        18
    mengyaoss77  
       2018-05-15 19:34:48 +08:00
    用 python 预处理一遍,再用 Java 去取呗
    motoko
        19
    motoko  
       2018-05-15 19:40:49 +08:00
    不想用循环,那就递归嘛~~
    def combine(pre, v2, idx):
    if idx >= len(v2):
    print pre
    return
    v1, idx = v2[idx], idx + 1
    for c in v1:
    combine(pre + str(c), v2, idx)

    if __name__ == '__main__':
    v2 = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 'a', 'b']]
    combine('', v2, 0)
    ~
    wanganjun
        20
    wanganjun  
       2018-05-15 19:57:39 +08:00 via iPhone
    偷懒的办法:把数组元素插入到内存表里面,一个数组一个表,然后连表查询......
    shalk
        21
    shalk  
       2018-05-15 21:05:25 +08:00 via iPhone   1
    n 个数组,把迭代器都取出来. 做成一个列表,整数进位一样. 例如 n 为 4,迭代器数组指向的是 0,0,0,0,再一次就是 0,0,0,1 当低位,hasnext 到头了,就进位,下一个迭代器移动,并且把本迭代器回拨到 0. 最后整个封装成一个 generator
    wr410
        22
    wr410  
       2018-05-15 21:54:06 +08:00   1
    你这个直接说“ CrossJoin ”或者笛卡尔积就专业了。

    具体实现上面都有,就不班门弄斧了。
    shalk
        23
    shalk  
       2018-05-15 22:45:39 +08:00
    电脑上补代码
    ```


    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;

    public class Permutation {
    interface Generator<T> {
    T next();

    boolean hasNext();
    }

    static class PermutationGenerator implements Generator<List<Integer>> {
    final private int[] index;
    final List<List<Integer>> nums;
    private boolean hasNext = true;

    public PermutationGenerator(List<List<Integer>> nums) {
    this.nums = nums;
    index = new int[nums.size()];
    }

    @Override
    public List<Integer> next() {
    List<Integer> ret = new ArrayList<>();
    if (!hasNext)
    return ret;

    for (int i = 0; i < index.length; i++) {
    ret.add(nums.get(i).get(index[i]));
    }

    int resetCount = 0;
    for (int i = 0; i < index.length; i++) {
    if (index[i] < nums.get(i).size() - 1) {
    index[i]++;
    break;
    } else {
    index[i] = 0;
    resetCount++;
    }
    }

    if (resetCount == index.length) {
    hasNext = false;
    }
    return ret;
    }

    @Override
    public boolean hasNext() {
    return hasNext;
    }
    }


    public static void main(String[] args) {
    List<List<Integer>> data = Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6), Arrays.asList(7, 8, 9));
    Generator<List<Integer>> gen = new PermutationGenerator(data);
    while (gen.hasNext()) {
    System.out.println(gen.next());
    }
    }
    }

    ```
    BBCCBB
        24
    BBCCBB  
       2019-07-06 21:31:00 +08:00
    你可以参考 leetcode 17 题
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     876 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 21:13 PVG 05:13 LAX 14:13 JFK 17:13
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86