Delete
:
a = Array[List, {4, 4}];
Delete[a, Array[{#, #} &, 4]]
{{{1, 2}, {1, 3}, {1, 4}},
{{2, 1}, {2, 3}, {2, 4}},
{{3, 1}, {3, 2}, {3, 4}},
{{4, 1}, {4, 2}, {4, 3}}}
Or, inspired by kglr's answer, with Pick
and IdentityMatrix
:
Pick[a, IdentityMatrix[4], 0]
{{{1, 2}, {1, 3}, {1, 4}},
{{2, 1}, {2, 3}, {2, 4}},
{{3, 1}, {3, 2}, {3, 4}},
{{4, 1}, {4, 2}, {4, 3}}}
Benchmark
With many methods provided I think it is time for a benchmark. I do not have Nothing
in version 10.1 so I shall use my old standby "vanishing function" from How to avoid returning a Null if there is no "else" condition in an If contruct in its place.
n = 1000;
(* for post processing methods this timing must be included in the total *)
a = Array[List, {n, n}]; // RepeatedTiming // First
DeleteCases[a, {a_, a_}, 2] // RepeatedTiming // First
Table[If[i == j, ## &[], {i, j}], {i, n}, {j, n}] // RepeatedTiming // First
Partition[#, n - 1] &@Permutations[Range@n, {2}] // RepeatedTiming // First
Select[#, DuplicateFreeQ] & /@ Outer[List, Range@n, Range@n] //
RepeatedTiming // First
Delete[a, Array[{#, #} &, n]] // RepeatedTiming // First
Partition[SparseArray[ConstantArray[1, {#, #}] - IdentityMatrix[#]][
"NonzeroPositions"], # - 1] &[n] // RepeatedTiming // First
Array[List, {n, n}, {1, 1}, DeleteCases[{##}, {a_, a_}, {2}] &] //
RepeatedTiming // First
Pick[a, IdentityMatrix[n], 0] // RepeatedTiming // First
0.00833
0.419
0.560
0.2670
0.491
0.00460
0.0351
0.412
0.0274
So even including the time to build a
my Delete
approach is considerably faster than any other method yet proposed. Second fastest is kglr's SparseArray
, or Pick
inspired by it.