2012-01-16 15 views
10

Tôi cần sử dụng If bên trong vòng lặp Table, ví dụ: Table[If[i< 3, i], {i, 5}] sẽ cung cấp cho {1, 2, Null, Null, Null}Làm thế nào để loại bỏ biểu tượng Null trong một Bảng trong Mathematica?

Nhưng tôi muốn kết quả là {1,2}.

Mọi sự khắc phục cho điều này?

EDIT:
gì nếu chúng ta xem xét Table[If[i< 3, f[i]], {i, 5}] mang đến cho {f[1], f[2], Null, Null, Null}

+0

câu hỏi Hơi liên quan: http://stackoverflow.com/q/ 6313505/618728 –

+0

Câu hỏi liên quan: http://mathematica.stackexchange.com/questions/3700/how-to-avoid-returning-a-null-if-there-is-no-else-condition-in-an-if -contruct – anderstood

Trả lời

27

ngắn gọn:

Table[If[i < 3, i, ## &[]], {i, 5}] 

Điều này hoạt động vì chức năng ## & không đánh giá ngay lập tức.

## & là chức năng "biến mất".

{1, 2, ## &[], 3, 4} 
----> {1, 2, 3, 4} 

Xem SlotSequence để biết thêm thông tin.

+5

+1 để nhắc mọi người về '## & []'. –

+1

@Leonid cảm ơn vì đã cho thấy hoặc nhắc tôi về điều đó vài tháng trước. –

+3

Tôi nghĩ đây là phát minh của bạn. Tôi thường sử dụng 'Sequence @@ {}', không phải là thanh lịch (và cũng có thể chậm hơn một chút). –

14

Nếu bạn cần phải loại bỏ nó từ danh sách có sẵn, bạn có thể sử dụng

DeleteCases[list, Null] 

hoặc

list /. Null -> Sequence[] 

(cao hơn một chút).


Về Table dụ bạn ở trên, lưu ý đầu tiên mà dấu phẩy thứ hai trong If là không cần thiết (và thậm chí được nhấn mạnh trong màu hồng):

list = Table[If[i < 3, i], {i, 5}] 

Để lọc các yếu tố bảng bằng một điều kiện, có lẽ bạn muốn sử dụng một cái gì đó tương tự như

list = Select[Table[i, {i, 5}], # < 3 &] 

thay thế.


Cuối cùng, nếu bạn cần để tạo ra các danh sách mà không bao giờ thêm các yếu tố từ chối với nó (để tiết kiệm bộ nhớ), tôi đề nghị sử dụng ReapSow:

[email protected][If[i < 3, Sow[i]], {i, 5}] 
list = %[[2, 1]] 

tôi đã không thực sự xác nhận các sử dụng bộ nhớ của điều này so với một đồng bằng Table, và lưu ý rằng nếu bạn tạo ra chỉ số, có thể được lưu trữ trong một packed array, xây dựng Table có thể có nhiều bộ nhớ hiệu quả hơn. Mặt khác, nếu bạn tạo ra một số lượng lớn các biểu thức chung chung, phần lớn trong số đó sẽ bị từ chối trong If, Sow/Reap có thể tốt hơn.

+0

+1. Tôi thực sự đã thực hiện đề xuất cuối cùng của bạn với 'Reap-Sow' trong toàn bộ tính tổng quát trong câu trả lời tôi liên kết, trong câu trả lời của tôi (chỉ có thể là cú pháp cho điều kiện có thể thân thiện hơn). –

6

Thay vào đó, bạn có thể sử dụng biến thể của Table từ this answer, được thiết kế đặc biệt cho việc xây dựng bảng có điều kiện. Đây là giao diện của nó:

In[12]:= tableGenAltMD[i,{i,5},#<3&] 
Out[12]= {1,2} 

Đối số cuối cùng là hàm đại diện cho điều kiện. Nó thực sự sẽ là tốt đẹp để cũng có cú pháp, nơi người ta có thể sử dụng trực tiếp i (và/hoặc các biến lặp khác), và cú pháp này có lẽ không khó để thêm vào.

+0

Vui lòng xem xét minh họa tại sao điều này có thể được ưu tiên hơn cho câu trả lời đơn giản mà tôi đưa ra dưới đây. –

+1

@Mr. Wizard Với một lý do rất đơn giản: đây là một chức năng chung (phiên bản của tôi). Nó xử lý trường hợp đa chiều là tốt, với một cú pháp thống nhất. Nó vẫn còn dễ đọc hơn, và sẽ dễ dàng hơn khi tôi thêm cú pháp để thay thế hàm bằng một biểu thức cho một điều kiện. Nếu nó đã là một chức năng tích hợp, hoặc chỉ đơn giản là WRI - đã được phê duyệt, sẽ không có câu hỏi về việc sử dụng bất cứ điều gì khác. Hãy tưởng tượng rằng bạn sẽ không nói 'Các trường hợp', và ai đó cung cấp cho bạn một (thực hiện ở cấp cao nhất). Bạn sẽ không sử dụng nó (nếu thực hiện là ok)? Phần lớn nó chỉ là về thói quen, quy ước, v.v. –

+0

Có lẽ bạn nên đưa nó vào câu trả lời của bạn? ;-) –

3

Nếu bạn sử dụng trình tự [] thay vì Null, sau đó bạn có thể làm

Table[If[i < 3, i, Hold[Sequence[]]] // ReleaseHold, {i, 5}] 

tôi muốn trong một thời gian dài mà Nếu sẽ có thuộc tính SequenceHold. Tôi nghĩ rằng tôi một lần đề xuất điều này với WRI, nhưng có lẽ (tốt?) Lý do cho Nếu không hat này thuộc tính. Người ta có thể cố gắng, nếu ai dám thay đổi biểu tượng built-in (mà ta nên có lẽ không làm):

Unprotect[If]; 
SetAttributes[If, SequenceHold]; 

Sau đó, trình tự [] trong Nếu sẽ chỉ làm việc:

Table[If[i < 3, i, Sequence[]], {i, 5}] 
+0

Rolf, vui lòng xem câu trả lời tôi vừa thêm vào. Tôi gần như đã chỉnh sửa câu hỏi của bạn thay vì đăng nó, nhưng tôi nhận ra rằng về cơ bản tôi sẽ thay thế câu trả lời của bạn với tôi, vì vậy tôi đã không. –

+0

Ông Wizard: rất đẹp! Tôi không biết về ## & @ [] là một chuỗi tương đương [] tương đương. –

1

Trong anwser trước, phần ## &[] có thể được thay thế bằng biểu tượng built-in Nothing

Table[If[i < 3, i, Nothing], {i, 5}] 

cho

{1, 2}