How to delete duplicate elements from associative array and Queue in System Verilog

Associative array :

int age[string];
    age["bob"] = 32;
    age["timmy"] = 4;
    age["tyrian"] = 31;
    age["sara"] = 2; 
    age["beema"] = 4;
    age["jack"]=31;

Queue:

int q_int[$];
q_int = {500,1000,500,200,400,500,600,700,900};

In reply to ritheshraj:

For a queue, you can refer the following code:


    int index[$];
    do begin
      index = q_int.find_index(x) with (x == 500);
      if(index.size()) begin
        q_int.delete(index.pop_front());
      end
    end
    while(index.size());

Or this way:


    for(int i = 0; i < q_int.size(); i++) begin
      if(q_int[i] == 500) begin
        q_int.delete(i--);
      end
    end

In reply to chris_le:

What’s that fixed value 500? How do you know the duplicated item? How about more than 1 duplicated item = =a

For the queue, way too simple.
For the associative array, I have a way to detect duplicated element, but the question is which key we should keep? it’s not clear to me. check my code.


module automatic test;

  // access queue
  function void find_unique_from_q;
    int q_int[$];
    q_int = {500,1000,500,200,400,500,600,700,900};
    q_int= q_int.unique();
  endfunction
  
  // access hash
  function void find_unique_from_hash;
    int age[string];
    int element[$];
    int ret[$];
    age["bob"] = 32;
    age["timmy"] = 4;
    age["tyrian"] = 31;
    age["sara"] = 2; 
    age["beema"] = 4;
    age["jack"]=31;
    
    element = age.find with(1);
    ret = element.unique(); 
    // use ret to update age hash_table
    // but you didn't mention which key we should keep, (beema or timmy?)
  endfunction

initial begin
 find_unique_from_hash();
 find_unique_from_q();
end

endmodule


In reply to javatea:

Depending on the question, I am not sure what did he want. If he wants to get unique elements from a queue, he may use your way. But if he wants to delete a element which occurs many positions (duplicate) in that queue, he can use my way.

In reply to javatea:

Regarding associate array sorting assuming I don’t know the value and key stored in it. So how to remove duplicates . To your question regarding “beema” or “timmy” i need to keep beema as I am following alphabetical order

In reply to chris_le:

haha
how do I want to remove 100 different duplicated items?
copy & paste 100 times? you are talking a joke…

In reply to javatea:

Common, at the first time I saw the question, I though he wanted to delete a specified element (which already known) in a queue. Turns out, he wanted to remove all duplicated elements and got the unique queue.
However, sometimes you will have the problem that you need my solution code. I give you one example: When you implement scoreboard, you push all expected transactions to a queue (can be duplicated). And you need to remove one by one from the queue after you finish checking/comparing them. You can’t just use .unique method in that queue, right?

About removing 100 different duplicated items, just loop them and remove them from a queue.

In reply to chris_le:

do you understand what’s the difference between “100 different duplicated items” and “duplicated 100 items”?
if you don’t understand, then don’t provide the answer e.g. just “loop them”
be clear before answering something. lol
I forget to unsubscribe this thread. wasting my time on blue Monday

In reply to javatea:
Haha, that’s what I thought about you. Maybe you need more explanation:
I said, just “loop them”, it meant exactly loop them. Get it? and I don’t need copy paste 100 times.


int q_int[$];
q_int = {500,1000,500,200,400,500,600,700,900};

for(int i = 0; i < q_int.size(); i++) begin
  for(int j = i+1; j < q_int.size(); j++) begin
    if(q_int[j] == q_int[i]) begin
      q_int.delete(j--);
    end
  end
end

module test;

int q_int[$];
int duplicate_aa[int];

int age[string];
string duplicate_aa2[int];

initial begin
  q_int = {500,1000,500,200,400,500,600,700,900};
  foreach(q_int[i]) duplicate_aa[q_int[i]]++;
  q_int = {};
  foreach(duplicate_aa[i])
    q_int.push_back(i);
  $display("After Deletion Duplicate array =%p",q_int);
end

initial begin
    age["bob"] = 32;
    age["timmy"] = 4;
    age["tyrian"] = 31;
    age["sara"] = 2; 
    age["beema"] = 4;
    age["jack"]=31;

    foreach(age[name]) duplicate_aa2[age[name]] = name;
    age.delete();
    $display("\nAfter Deletion Duplicate array ===== ");
    foreach(duplicate_aa2[num]) age[num] = duplicate_aa2[num];
    foreach(age[name]) $display("age[%0s]=%0d",age[name],name);
end
endmodule

OUTPUT::

After Deletion Duplicate array ='{200, 400, 500, 600, 700, 900, 1000} 

After Deletion Duplicate array ===== 
age[sara]=2
age[timmy]=4
age[tyrian]=31
age[bob]=32

In reply to naaj_ila:

Thank you for the solution naaj_ila

Can you please explain me difference between q_int.delete(j) and q_int.delete(j–)

In reply to narendrareddy:

q_int.delete(j--);

is the same as

q_int.delete(j)
j = j - 1;

It needed to repeat the same index in the for-loop. The next index has just moved in to the current index position.

But this problem would be much easer to solve using unique() and unique_index().

I have written a code to remove the dublicate elements in an array

module tb;
integer A[$];
initial
begin
	A={5,5,5,2,2,2,2,2,2,123,321,567,765,5,5,5,5,5};
	for(int i=0;i<=(A.size()-1);i=i+1)
	begin
		for(int j=i+1;j<=(A.size()-1);j=j+1)
		begin
			if(A[i]==A[j])
			begin
				A.delete(j);
			end		
		end
		$display(A[i]);

	end
end
endmodule

The above code is not working.
If I replace the A.delete(j) with A.delete(j–) the code is woking fine. Can anyone please explain me in detail, why the code is not working with A.delete(j) and it is working with A.delete(j–).

In reply to narendrareddy:

I suggest stepping through the code interactively, or adding a $display

$display(i,,j,,A[i],,A[j]);
if(A[i]==A[j])

Thank you dave_59 for giving me the approach to debug my issue.