Что нового

[Массивы] Удаление дубликатов в двумерном массиве.

CheFix

Новичок
Сообщения
11
Репутация
0
Добрый день, прошу вас о помочь с двумерным массивом.

Есть двумерный массив вида: $aArr [13][2]
В столбце: $aArr [$i][0] находятся отсортированные, по возрастванию, целые числа, которые иногда повторяются.
В столбце: $aArr [$i][1] находится текстовая информация.

Пример массива:
[1][один]
[1][два]
[2][три]
[2][четыре]
[3][пять]
[3][шесть]
[5][девять]
[5][десять]
[6][одиннадцать]
[6][двенадцать]

Как должно быть:
[1][один]
[4][семь]
[5][восемь]
[2][три]
[3][пять]
[4][семь]
[5][восемь]
[6][одиннадцать]

В целом не важно какой будет текст во втором столбике - главное, чтобы в первом столбце не было повторений.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Можно так :
Код:
#include<Array.au3>
Dim $aArr [10][2]=[ _ 
						[1, 'один'],  _ 
						[1, 'два'],  _ 
						[2, 'три'],  _ 
						[2, 'четыре'],  _ 
						[3, 'пять'],  _ 
						[4,'шесть'],  _ 
						[5, 'девять'],  _ 
						[5, 'десять'],  _ 
						[6, 'одиннадцать'],   _ 
						[6, 'двенадцать']]
						
_ArrayDisplay($aArr , "$aArr")

$sStr='|'
For $i=UBound($aArr)-1 To 0 Step -1
	If StringInStr($sStr, "|" & $aArr[$i][0] & "|") Then
		_ArrayDelete($aArr, $i)
	Else
		$sStr &=$aArr[$i][0] & "|"
	EndIf
Next

_ArrayDisplay($aArr , "$aArr")



Добавлено:
Сообщение автоматически объединено:

Правда в том варианте остается последний из дубликатов
Если это критично , то можно оставить 1-й :
Код:
#include <Array.au3>
Dim $aArray [10][2]=[ _ 
						[1, 'один'],  _ 
						[1, 'два'],  _ 
						[2, 'три'],  _ 
						[2, 'четыре'],  _ 
						[3, 'пять'],  _ 
						[4,'шесть'],  _ 
						[5, 'девять'],  _ 
						[5, 'десять'],  _ 
						[6, 'одиннадцать'],   _ 
						[6, 'двенадцать']]

_ArrayDisplay($aArray, "$aArray")

Dim $aNewArray [UBound ($aArray)][2]
$sStr='|'
$j=0

For $i=0 To UBound ($aArray)-1
	If Not StringInStr($sStr, "|" & $aArray[$i][0] & "|") Then
		$aNewArray[$j][0]=$aArray[$i][0]
		$aNewArray[$j][1]=$aArray[$i][1]
		$j+=1
		$sStr &=$aArray[$i][0] & "|"
	EndIf
Next

ReDim $aNewArray [$j][2]

_ArrayDisplay($aNewArray , "$aNewArray")
 
Автор
C

CheFix

Новичок
Сообщения
11
Репутация
0
Спасибо за помощь! :smile:
Все работает.


Добавлено:
Сообщение автоматически объединено:

Код с комментариями, если кто-то не будет понимать.
Надеюсь описал понятно.

Код:
$sStr='|'

For $i=UBound($aArr)-1 To 0 Step -1 ;от конца массива до его начала
    If StringInStr($sStr, "|" & $aArr[$i][0] & "|") Then  ;если в  строке $sStr уже есть  число из  массива $aArr
        _ArrayDelete($aArr, $i)   ;то удаляем строку с числом из массива
    Else
        $sStr &=$aArr[$i][0] & "|"  ;если нет такого числа, то записываем его в строку для дальнейшей проверки
    EndIf
Next


Код:
Dim $aNewArray [UBound ($aArray)][2]
$sStr='|'
$j=0  ;счётчик строк

For $i=0 To UBound ($aArray)-1  ;от начала массива до конца
    If Not StringInStr($sStr, "|" & $aArray[$i][0] & "|") Then ;если в строке $sStr нет числа из массива $aArr
        $aNewArray[$j][0]=$aArray[$i][0]   ;то записываем строку с числом в новый массив
        $aNewArray[$j][1]=$aArray[$i][1]   ;и строку с текстом тоже
        $j+=1   ;увеличиваем счётчик
        $sStr &=$aArray[$i][0] & "|"   ;записываем число в строку для дальнейшего сравнения
    EndIf
Next

ReDim $aNewArray [$j][2]   ;пересоздаём массив, чтобы обрезать пустые строки



Добавлено:
Сообщение автоматически объединено:

Способ со строкой работает для массива с малой размерностью.
Если массив будет большим, то скрипт начинает жрать память, пока не вылетит. :scratch:


Добавлено:
Сообщение автоматически объединено:

Потестил скрипт - это массив очень большой.
:scratch:


Добавлено:
Сообщение автоматически объединено:

Так по моему тоже работает (без строки):
Код:
#include<Array.au3>
Dim $aArr [10][2]=[ _ 
                        [1, 'ccvcv'],  _ 
                        [1, 'bnbnbn'],  _ 
                        [2, 'nmnmnm'],  _ 
                        [2, 'nmnmnmnmn'],  _ 
                        [3, 'm,m,m,m,'],  _ 
                        [4, 'bnbnb'],  _ 
                        [5, 'bnbnbn'],  _ 
                        [5, 'bbbnbn'],  _ 
                        [6, 'bnbnbnbnbn'],   _ 
                        [6, 'bbnbnbn']]
                        
_ArrayDisplay($aArr , "$aArr")

$j=0
For $i=UBound($aArr)-1 To 0 Step -1
   If $aArr[$i][0]=$aArr[$i-1][0] Then
	  _ArrayDelete($aArr, $i)
	  $i-=1      
   EndIf
Next

_ArrayDisplay($aArr , "$aArr")
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Та что вы мучаете себя как при старом режиме?!
Нет чтобы по-настоящему!

Код:
#include <Array.au3>

Dim $aArray [10][2]=[ _
                        [1, 'один'],  _
                        [1, 'два'],  _
                        [2, 'три'],  _
                        [2, 'четыре'],  _
                        [3, 'пять'],  _
                        [4,'шесть'],  _
                        [5, 'девять'],  _
                        [5, 'десять'],  _
                        [6, 'одиннадцать'],   _
                        [6, 'двенадцать']]

$uniArray = _ArrayUnique($aArray)

Dim $aNewArray [$uniArray[0]][2]

For $i = 1 To $uniArray[0]
	$aNewArray[$i-1][0] = $uniArray[$i]
	$aNewArray[$i-1][1] = $aArray[_ArraySearch($aArray, $uniArray[$i], 0, 0, 0, 1)][1]
Next

_ArrayDisplay($aNewArray, "")
 
Автор
C

CheFix

Новичок
Сообщения
11
Репутация
0
Куча вариантов уже ;D
Спасибо за помощь!
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Поскольку массив отсортирован -необходимость в строке отпадает.
Код:
Dim $aNewArray [UBound ($aArray)][2]

$j=0
$iDefault=0
For $i=0 To UBound ($aArray)-1
	If $aArray[$i][0]<> $iDefault Then
		$aNewArray[$j][0]=$aArray[$i][0]
		$aNewArray[$j][1]=$aArray[$i][1]
		$j+=1		
	EndIf
   $iDefault =$aArray[$i][0]
Next

ReDim $aNewArray [$j][2]

_ArrayDisplay($aNewArray , "$aNewArray")


Наверняка будет быстрее,чем с _ArrayUnique и _ArraySearch
 
Верх