2013-10-21 174 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; 
}