2013-10-21 173 views
0

我有一個列表:冗餘代碼

id num1 ... 
----------- 
1 123 ... 
1 456 ... 
2 789 ... 
2 666 ... 

,並希望基於它創建一個對象數組:

{ 1, [123, 456], [...] }, 
{ 2, [789, 666], [...] } 

這裏是我的僞代碼:

int previous_id = -1; 
array a1 = null; // B 
array a2 = null; // B 
array a3 = null; // B 
array a4 = null; // B 
while (++c) { // c is a pointer pointing to the list 
    if (c.id != previous_id && previous_id != -1) { 
    j[i++].id = previous_id; // A 
    j[i++].data1 = a1;   // A 
    j[i++].data2 = a2;   // A 
    j[i++].data3 = a3;   // A 
    j[i++].data4 = a4;   // A 
    a1 = null; // B 
    a2 = null; // B 
    a3 = null; // B 
    a4 = null; // B 
    } 
    a1.add(c.num1); 
    a2.add(c.num2); 
    a3.add(c.num3); 
    a4.add(c.num4); 
    previous_id = c.id; 
} 
j[i++].id = previous_id; // A 
j[i++].data1 = a1;   // A 
j[i++].data2 = a2;   // A 
j[i++].data3 = a3;   // A 
j[i++].data4 = a4;   // A 

它正在工作,但有一些冗餘代碼,即A和B

是否可以合併它們使其更加簡潔明瞭?

+2

爲什麼你稱之爲多餘?如果部分代碼不清楚,則爲該語句添加註釋。你的意思是低效嗎? –

+0

取決於實現語言中'j [i ++]。data = a'的語義 - 如果它保留對對象的「實時」引用,以便後續的'a.add(c.num)'調用將被觀察到在'data'成員中,那麼你可以切換東西。 OTOH如果'data'當時需要'a'的副本,並且從不觀察更新,我想不出更新的方式 –

+0

@AhishekBansal更新了我的問題。是的,也許它不是多餘的,它看起來不夠簡潔。當我完成我的代碼時,我覺得應該有一種方法將'A'和/或'B'合併在一起,但不知道該怎麼做。 – Deqing

回答

1

有一對夫婦的事情可以做,以提高你的代碼的清晰度,如果是這樣的目標。

而不是使用不同的名稱,使用索引。

「數組」沒有定義,所以我想這是一個表的東西。你可能有這樣的事情:

#define NB_ARRAYS 4 
    array myArrays[NB_ARRAYS]; 

這樣一來,你就可以遍歷數組的,並最終隨時更改,今後陣列的數量。

好的想法是,你不再需要單獨列出你的數組,單個循環就足夠了。因此:

a1 = null; // B 
    a2 = null; // B 
    a3 = null; // B 
    a4 = null; // B 

成爲

{ int i; for (i=0; i<NB_ARRAYS; i++) myArrays[i] = NULL; } 

你可能會抱怨,這並不比第一個版本更好,但實際上你可以隱藏這個宏背後的複雜性:

#define INIT_ARRAYS(a) { int i; for (i=0; i<NB_ARRAYS; i++) a[i] = NULL; } 

甚至內聯函數背後更好:

static inline void initArrays(array* a) { int i; for (i=0; i<NB_ARRAYS; i++) a[i] = NULL; } 

所以它變成:

initArrays(myArrays); 

這是更清楚。

重複使用相同的原則,這會導致你的代碼是這樣的:

int previous_id = -1; 
    initArrays(myArrays); 

    while (++c) 
    { // c is a pointer pointing to the list 
     addToArrays(myArrays, c); 
     if (c.id != previous_id && previous_id != -1 || c.islast()) 
     { 
      j[i++].id = previous_id; // A 
      setArrays(j, i, myArrays); i+=NB_ARRAYS; 
      if (!c.islast()) { initArrays(myArrays); } 
     } 
    } 
    previous_id = c.id; 

這應該是更容易閱讀,因此,更容易維護。

另外:儘量使用更容易閱讀變量。在這個例子中,我不知道c,i或j代表什麼,也不知道它們在哪裏定義。使用5-6個字符來正確命名它們並沒有多少成本,並且確實有助於代碼維護。

+0

很好的建議。其實在我的代碼中沒有這樣的a1 a2 ......他們已經命名爲諸如「phoneNumber」,「familyName」,「honorificPrefix」......並且c實際上是一個「遊標遊標」,並且它需要通過' getContentResolver()。query(...)'和'++ c'爲'cursor.moveToNext()',這些數組實際上是JSONObjects,字符串和JSONArray,它們需要通過不同的方式初始化,比如'new JSONObject (someString)''或'new JSONArray(object)',...我只想專注於如何改進代碼本身的結構,所以編寫了一個簡單的僞代碼。 – Deqing

0

你的代碼有點太僞代碼 - 我的喜好 - 建議非常依賴於你的實際實現。不過,我會提出一些想法。

A部分:

struct的用C將允許你這樣做:

someStruct temp = {previous_id, a1, a2, a3, a4}; 
j[i++] = temp; 

對於B部分:

我認爲null實際指的是一個空的數組,而不是一個數組,你可能有一個固定長度的數組,其長度爲單獨的長度指示符。

您可以始終有一個長度數組,而不是一個2D主數組,而整個長度數組爲memset而不是逐個設置它們。

0

只是找到了一種方法來合併A,避免一定復位B

int previous_id = -1; 
array a1 = null; // B 
array a2 = null; // B 
array a3 = null; // B 
array a4 = null; // B 
while (++c) { // c is a pointer pointing to the list 
    a1.add(c.num1); 
    a2.add(c.num2); 
    a3.add(c.num3); 
    a4.add(c.num4); 
    if (c.id != previous_id && previous_id != -1 
     || c.islast()) { 
    j[i++].id = previous_id; // A 
    j[i++].data1 = a1;   // A 
    j[i++].data2 = a2;   // A 
    j[i++].data3 = a3;   // A 
    j[i++].data4 = a4;   // A 
    if (!c.islast()) { 
     a1 = null; // B 
     a2 = null; // B 
     a3 = null; // B 
     a4 = null; // B 
    } 
    } 
    previous_id = c.id; 
}