'Concatenation of array and array element on i'th position

Having some declared types and an array:

type player = Orange | Red | Blue | White ;;
type piece = 
    Knight of player | Town of player 
  | City of player   | Road of player 
  | Wool of player   | Brick of player 
  | Lumber of player | Grain of player 
  | Ore of player ;;

let posessions =
  [| Ore Orange; Road Red; Ore Blue; 
     Ore White; Lumber White; Ore Red; 
     Knight Red; Road Orange; Lumber Red; 
     Brick Red; City White; Lumber White; 
     Wool Red; City White; Ore White; 
     Brick White; Road Blue; Lumber Blue; 
     Grain Orange; Wool Red; Road White; 
     Knight White; Grain White; Wool Orange; 
     City Blue; Ore Orange; Knight Orange; 
     Brick White; Ore Red; Ore White; 
     Road Orange; Knight Red; Lumber Orange; 
     Wool Orange; City Orange; Wool Blue; 
     Lumber White; City Red; Grain Red; 
     Lumber Red; Ore White; Grain White; 
     Brick Orange; Brick White; Road Blue; 
     Grain Red; Ore White; City White; 
     Road White; Knight Orange; Brick Red; 
     Ore White; Lumber Orange; Ore Blue; 
     Road Blue; Brick White; Brick Orange; 
     Ore Orange; Ore Blue; Ore Orange; 
     Ore Orange; Brick Orange; Brick White; 
     Road Orange; Lumber White; Knight Red; 
     Brick White; Brick Orange; Road Blue; 
     Brick Orange; Lumber Blue; Road Blue; 
     Ore Red; Grain Blue; Wool Red; 
     Town Red; Ore Orange; Lumber White; 
     Road Red; Road Blue; Town Blue; 
     Wool Red; Lumber Blue; Wool Blue; 
     Town Red; Grain Orange; Brick Blue; 
     Knight Red; Wool White; Ore Orange; 
     Ore Blue; Lumber White; Wool White; 
     Brick Orange; Ore Blue; Grain Red; 
     Wool Blue; Road Red; Ore Blue; 
     Lumber Orange |];;

I have a task where I have to create a function filterbyplayer : player -> piece array -> piece array = <fun> that given a player and a piece array, it returns the subarray containing pieces that belong to that player.

So far, I did it just for the Orange color to see if It would work so i can basically paste it for every other case, since there's only 4. My code so far:

let array2 = [| |];; 
let rec filterbyplayer = fun value array ->
  if value = Orange then
    let n = Array.length array in
    for i = 0 to n - 1 do 
      if array.(i) = (Knight Orange) || array.(i) = (Town Orange) ||  array.(i) = (City Orange) || 
         array.(i) = (Road Orange) || array.(i) =  (Wool Orange) || array.(i) =  (Brick Orange) || 
         array.(i) = (Lumber Orange) ||  
         array.(i) = (Grain Orange) ||  array.(i) = (Ore Orange) 
      then array2 = Array.append  array(i) ( filterbyplayer Orange Array.(i+1))
      else filterbyplayer Orange Array.(i+1)
    done;;

I'm not sure whether It'working or not because I can't seem to concatenate arrays in the right way. What I wanted to do in this line then array2 = Array.append array(i) ( filterbyplayer Orange Array.(i+1)) is to have array2 be equal to ith element of the array (array(i)) AND the called function on the array(i + 1) for the next element (with Color orange obviously as the value). The error I'm always getting is: Error: This expression has type piece but an expression was expected of type a array. Any tips on how to merge those elements of the array into the new one?



Solution 1:[1]

I'd rather write something like this:

let filterbyplayer p u =
    u
 |> Array.to_seq
 |> Seq.filter (function
     | Knight x
     | Town x
     | City x
     | Road x
     | Wool x
     | Brick x
     | Lumber x
     | Grain x
     | Ore x -> x = p)
 |> Array.of_seq

Hope it helps

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1