Randomly Choosing two objects from an array and switching their positions

I have a 6x9 grid of tiles, I want it so every 2-5 seconds two random tiles switch positions, I have the array set up and the invokerepear method but I do not know how to randomly select two objects from the array in the grid and switch their positions.

This is what I have far

public GameObject _indicator;//The indicator to know the selected tile
	public GameObject[,]  _arrayOfShapes;//The main array that contain all games tiles
	private GameObject _currentIndicator;//The current indicator to replace and destroy each time the player change the selection
	private GameObject _FirstObject;//The first object selected
	private GameObject _SecondObject;//The second object selected
	public GameObject [] _listOfGems;//The list of tiles we can see in the game 
	public int _gridWidth;//the grid number of cell horizontally
	public int _gridHeight;//the grid number of cell vertically
   
	// Use this for initialization
	void Start () {
		//Initializing the array with _gridWidth and _gridHeight passed in parameter
		_arrayOfShapes = new GameObject[_gridWidth, _gridHeight];
		//Creating the gems from the list of gems passed in parameter
		for ( int i = 0; i <= _gridWidth-1; i++){
			for ( int j = 0; j <= _gridHeight-1; j++){
				var gameObject = GameObject.Instantiate(_listOfGems[Random.Range(0, _listOfGems.Length)] as GameObject, new Vector3(i, j, 0), transform.rotation) as GameObject;
				_arrayOfShapes[i,j]= gameObject;
         }
		}
		//Adding the star effect to the gems and call the DoShapeEffect continuously
   InvokeRepeating("DoShapeEffect", 1f, 0.21F);
	}
		
	void Shuffle ()
	{

	}

	// Update is called once per frame
	void Update () {

		InvokeRepeating ("Shuffle", 2, Random.Range(2,5));

// to pick random elements

int x1, y1, x2, y2;
        
x1 = Random.Range(0, _arrayOfShapes.GetLength(0));
x2 = Random.Range(0, _arrayOfShapes.GetLength(0));
y1 = Random.Range(0, _arrayOfShapes.GetLength(1));
y2 = Random.Range(0, _arrayOfShapes.GetLength(1));

// to swap array positions

GameObject temp = _arrayOfShapes[x1, y1];
_arrayOfShapes[x1, y1] = _arrayOfShapes[x2, y2];
_arrayOfShapes[x2, y2] = temp;

// OR to swap physical locations

Vector3 temp = _arrayOfShapes[x1, y1].transform.position;
_arrayOfShapes[x1, y1].transform.position = _arrayOfShapes[x2, y2].transform.position;
_arrayOfShapes[x2, y2].transform.position = temp;

Little code like this, not tested but should work:

 void Shuffle()
    {
        //get random coordinates for both elements 
        int x1 = Random.Range(0,_arrayOfShapes.GetLength(0)-1);
        int y1 = Random.Range(0,_arrayOfShapes.GetLength(1)-1);
        int x2 = Random.Range(0,_arrayOfShapes.GetLength(0)-1);
        int y2 = Random.Range(0,_arrayOfShapes.GetLength(1)-1);

        //if by any luck the point to the same element start over
        if(_arrayOfShapes[x1,y1] == _arrayOfShapes[x2,y2])
        {
        Shuffle();
        }
        else
        {
            //if they are different swap
            //create tmp gameobject and save first element there
            GameObject tmp = _arrayOfShapes[x1,y1];
            //replace first element by seconds 
            _arrayOfShapes[x1,y1] = _arrayOfShapes[x2,y2];
            //copy first elemtn tmp to second
            _arrayOfShapes[x2,y2] = tmp;
        }

      
    }	// Update is called once per fr

If you want to swap (move the gameobjects) you might do something like this

 //if they are different swap
            //create tmp gameobject and save first element there
          Vector3 tmp = _arrayOfShapes[x1,y1].transform.position;
            //replace first element by seconds 
            _arrayOfShapes[x1,y1].transform.position = _arrayOfShapes[x2,y2].transform.position;
            //copy first elemtn tmp to second
            _arrayOfShapes[x2,y2].transform.position = tmp;

Here is the next part of the code after the part I’ve already posted

void Shuffle ()
	{
		x1 = Random.Range(0, _arrayOfShapes.GetLength(0));
		x2 = Random.Range(0, _arrayOfShapes.GetLength(0));
		y1 = Random.Range(0, _arrayOfShapes.GetLength(1));
		y2 = Random.Range(0, _arrayOfShapes.GetLength(1));

		Vector3 temp = _arrayOfShapes[x1, y1].transform.position;
		_arrayOfShapes[x1, y1].transform.position = _arrayOfShapes[x2, y2].transform.position;
		_arrayOfShapes[x2, y2].transform.position = temp;
	}

	// Update is called once per frame
	void Update () {
		
		bool shouldTransit = false;
		//Detecting if the player clicked on the left mouse button and also if there is no animation playing
		if (Input.GetButtonDown ("Fire1") && HOTween.GetTweenInfos()==null) {
		   
			Destroy(_currentIndicator);
			//The 3 following lines is to get the clicked GameObject and getting the RaycastHit2D that will help us know the clicked object
			Ray ray   = Camera.main.ScreenPointToRay (Input.mousePosition);
            RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
			if (hit.transform!=null)
            {  //To know if the user already selected a tile or not yet
               if ( _FirstObject == null ) _FirstObject = hit.transform.gameObject;
			   else {_SecondObject=  hit.transform.gameObject;
                    shouldTransit= true ; }

				_currentIndicator =  GameObject.Instantiate (_indicator,new Vector3( hit.transform.gameObject.transform.position.x,hit.transform.gameObject.transform.position.y,-1), transform.rotation) as GameObject ;
				//If the user select the second tile we will swap the two tile and animate them
				if (shouldTransit)
                {
					//Getting the position between the 2 tiles
					var distance = _FirstObject.transform.position - _SecondObject.transform.position;
					//Testing if the 2 tiles are next to each others otherwise we will not swap them 
					if (Mathf.Abs(distance.x) <= 1 && Mathf.Abs(distance.y) <= 1)
                    {   //If we dont want the player to swap diagonally
                        if (!_canTransitDiagonally  )
                        {
                            if (distance.x != 0 && distance.y != 0)
                            {
                                Destroy(_currentIndicator); 
                                _FirstObject = null;
                                _SecondObject = null; 
                                return;
                            }
                        }
                       //Animate the transition
                        DoSwapMotion(_FirstObject.transform, _SecondObject.transform);
						//Swap the object in array
						DoSwapTile(_FirstObject, _SecondObject, ref _arrayOfShapes);

                                                
                    }
                    else
                    {
                        _FirstObject = null;
                        _SecondObject = null;

                    }
                   Destroy(_currentIndicator);
                                       
                }
               
			}
          
		}
	}

    // Find Match-3 Tile
    private ArrayList FindMatch(GameObject[,] cells)
    {//creating an arraylist to store the matching tiles
        ArrayList stack = new ArrayList();
		//Checking the vertical tiles
        for (var x = 0; x <= cells.GetUpperBound(0); x++)
        {
            for (var y = 0; y <= cells.GetUpperBound(1); y++)
            {
                var thiscell = cells[x, y];
				//If it's an empty tile continue
                if (thiscell.name == "Empty(Clone)") continue;
                int matchCount = 0;
                int y2 = cells.GetUpperBound(1);
                int y1;
				//Getting the number of tiles of the same kind
                for (y1 = y + 1; y1 <= y2; y1++)
                {
                   if (cells[x, y1].name == "Empty(Clone)" || thiscell.name != cells[x, y1].name) break;
                    matchCount++;
                }
				//If we found more than 2 tiles close we add them in the array of matching tiles
                if (matchCount >= 2)
                {
                    y1 = Mathf.Min(cells.GetUpperBound(1) , y1 - 1);
                    for (var y3 = y; y3 <= y1; y3++)
                    {
                        if (!stack.Contains(cells[x, y3]))
                        {
                            stack.Add(cells[x, y3]);
                        }
                    }
                }
            }
        }
		//Checking the horizontal tiles , in the following loops we will use the same concept as the previous ones
        for (var y = 0; y < cells.GetUpperBound(1) + 1; y++)
        {
            for (var x = 0; x < cells.GetUpperBound(0) + 1; x++)
            {
                var thiscell = cells[x, y];
                if (thiscell.name == "Empty(Clone)") continue;
                int matchCount = 0;
               int x2 = cells.GetUpperBound(0);
                int x1;
                for (x1 = x + 1; x1 <= x2; x1++)
                {
                    if (cells[x1, y].name == "Empty(Clone)" || thiscell.name != cells[x1, y].name) break;
                    matchCount++;
                }
                if (matchCount >= 2)
                {
                    x1 = Mathf.Min(cells.GetUpperBound(0), x1 - 1);
                    for (var x3 = x; x3 <= x1; x3++)
                    {
                        if (!stack.Contains(cells[x3, y]))
                        {
                            stack.Add(cells[x3, y]);
                         }
                    }
                }
            }
        }
        return stack;
    }

    // Swap Motion Animation, to animate the switching arrays
    void DoSwapMotion(Transform a, Transform b)
    {
        Vector3 posA = a.localPosition;
        Vector3 posB = b.localPosition;
        TweenParms parms = new TweenParms().Prop("localPosition", posB).Ease(EaseType.EaseOutQuart);
        HOTween.To(a, 0.25f, parms).WaitForCompletion();
        parms = new TweenParms().Prop("localPosition", posA).Ease(EaseType.EaseOutQuart);
       HOTween.To(b, 0.25f, parms).WaitForCompletion();
    }


	// Swap Two Tile, it swaps the position of two objects in the grid array
	void DoSwapTile(GameObject a, GameObject b, ref GameObject[,] cells)
    {
        GameObject cell = cells[(int)a.transform.position.x, (int)a.transform.position.y];
        cells[(int)a.transform.position.x, (int)a.transform.position.y] = cells[(int)b.transform.position.x, (int)b.transform.position.y];
        cells[(int)b.transform.position.x, (int)b.transform.position.y] = cell;
    }