2013-06-05 2 views
1

Я пробовал различные перестановки array_unique и искал другие общие вопросы здесь, при удалении повторяющихся значений из массива, но я не могу установить ответ, который мне нужен. У меня есть массив, передаваемый по датам и значениям, и только хочу просмотреть значение DATE один раз за дату.PHP удалять повторяющиеся экземпляры дат в массиве

Я использую это для диаграммы Google и хочу, чтобы метки даты отображались только один раз для каждой даты. И я не хочу полностью удалить его, потому что я хочу, чтобы иметь возможность построить его на диаграмме.

Таким образом, пример массива передается:

["June 4",30],["June 4",35],["June 5",46],["June 5",38.33],["June 5",12] 

И как я хочу это:

["June 4",30],["",35],["June 5",46],["",38.33],["",12] 

Идеи?

+4

Создать ассоциативный массив от метки даты до значения? Таким образом, если вы добавите две записи с одинаковой меткой даты, вы получите только одну запись и, следовательно, только одно значение. – Patashu

+2

Я бы реструктурировал массив как массив («4 июня» => массив (30,35)) и т. Д. ... –

+0

У вас уже есть пример кода примера. То, как у вас есть, не будет работать так, как вы хотите, с его текущей структурой. Как вы получаете даты и значения для начала? –

ответ

0

Это возможное решение вашей проблемы, хотя я бы порекомендовал перестроить как Patashu & Nikola R.

$untrimmed = [["June 4",30],["June 4",35],["June 5",46],["June 5",38.33],["June 5",12]]; 
$trimmed = stripDates($untrimmed); 

function stripDates($dates) { 
    foreach($dates as $key=>$date) { 
     if ($key>0) { 
      if ($date[0] === $dates[$key-1][0]) { 
       $dates[$key][0] = ""; 
      } else if($dates[$key-1][0] === "") { 
       for ($i = $key-1; $i > -1; $i--) { 
        if ($date[0] === $dates[$i][0]) $dates[$key][0] = ""; 
        if ($dates[$key] != "") break; 
       } 
      } 
     } 
    } 
    return $dates; 
} 

// Note: This would require dates to be added chronically 
//Output: ["June 4",30],["",35],["June 5",46],["",38.33],["",12] 

Я бы рекомендовал что-то вроде этого:

$unconstructed = [["June 4",30],["June 4",35],["June 5",46],["June 5",38.33],["June 5",12]]; 
$constructed = constructAssoc($unconstructed); 

function constructAssoc($dates) { 
    $constructed = array(); 
    foreach($dates as $index=>$date) { 
     if (!array_key_exists($date[0], $constructed)) { 
      $constructed[$date[0]] = array("index"=>$index, "value"=>$date[1]); 
     } else { 
      array_push($constructed[$date[0], ["index"=>$index,"value"=>$date[1]]); 
     } 
    } 
    return $constructed; 
} 

//Output: ["June 4"=> [["index"=>0, "value"=>30], ["index"=>1, "value"=>35]], "June 5"=>[["index"=>2, "value"=>46], ["index"=>3, "value"=>38.33], ["index"=>4, "value"=>12]]] 

Примечание: Добавлен индекс в рекомендованном растворе, если более точное повторное строительство не требуется.

+0

Вложенный цикл в этом решении начнет занять много времени, если набор данных станет очень большим - это алгоритм O (n^2) – jcsanyi

+0

. Для вашего рекомендованного решения, как он возвращает его в формат, который ему нужен для построения диаграмм ? – jcsanyi

+0

Добавлен перерыв для лучшей производительности. И для второго комментария было бы невозможно получить их в том же положении, если вы не добавили каждый индекс внутри каждого значения. – leko

0

Поскольку вы используете данные для подачи на диаграмму google, я предполагаю, что вы точно знаете, что вам нужно в отношении выходных данных. Для улучшения способов структурирования данных уже есть некоторые предложения, но, вероятно, они не будут работать напрямую для диаграммы Google.

Как насчет этого?

$data = [["June 4",30],["June 4",35],["June 5",46],["June 5",38.33],["June 5",12]]; 
$found = array(); 
foreach ($data as $i => $x) { 
    if (in_array($x[0], $found)) { 
     $data[$i][0] = ''; 
    } else { 
     $found[] = $x[0]; 
    } 
} 
print_r($data); 

В принципе, это просто строит список дат, которые он уже видел. Мы просматриваем данные и проверяем, видели ли мы дату ... если у нас есть, мы очищаем ее от данных, иначе мы сохраним ее в списке, чтобы она была очищена в следующий раз.

Вот альтернативное решение, которое проверяет только для повторяющихся дат, которые подряда, в отличии от первого решения, которое удалит всех дубликатов. Это, вероятно, ближе к тому, что нужно для построения графиков:

$data = [["June 4",30],["June 4",35],["June 5",46],["June 5",38.33],["June 5",12]]; 
$last = ''; 
foreach ($data as $i => $x) { 
    if ($x[0] == $last) { 
     $data[$i][0] = ''; 
    } else { 
     $last = $x[0]; 
    } 
} 
print_r($data); 

В этом случае мы просто отслеживание последнего дня мы видели ... и если наша новая дата совпадает, мы очищаем его ,

Смежные вопросы