I'm working on an app that needs a function to return a value based upon
matching to 4 different sources and returns the most specific match that
meets a quality threshold.

Here is an example:

The last column of every table (e.g. city_sport) indicates the quality
threshold and the column before that is the value I'd like if the quality
threshold is above 3

The logic in words:

Search city_sport
if not found or quality not sufficient, search city
if not found or quality not sufficient search sport
if not found or quality not sufficient search item

The logic works. I wrote it quickly in J using my natural imperative
mindset. I then was able to very quickly translate it into C# (probably
demonstrating how imperative my mindset was)

J version: https://gist.github.com/joebo/381552e6ad106391e128
C# version: https://gist.github.com/joebo/a0ff7eb57ee15ea96c61

I'm looking for input on how to rewrite getVal to show improved
maintenance, conciseness over the C# version (subjective, I know)

Some half-baked thoughts:

1. Instead of using the if., at each step build up all the possible results
and find the result in the final step

Note: this will be searching a table of 180,000 rows so performance may
matter. The current J version doesn't short circuit, but it could fairly
easily

2. Some trick with agenda


Thanks for any input

Code below:

city_sport=: ' ' cut every <;._2 (0 : 0)
hat chicago baseball 1 5
hat chicago football 2 5
hat atlanta baseball 3 2
hat orlando football 3 3
glove orlando baseball 3 3
)

city=: ' ' cut every <;._2 (0 : 0)
hat chicago 1 5
hat atlanta 3 2
hat orlando 3 3
glove orlando 3 3
)

sport=: ' ' cut every <;._2 (0 : 0)
hat baseball 1 5
hat football 3 2
jersey soccer 3 4
)

item=: ' ' cut every <;._2 (0 : 0)
hat 1 5
jersey 2 4
)

NB. gets the count which is always the last column
getCtCol =: ([: ". [: > _1 { {) :: 0:

NB. gets the value which is always 2nd to last column
getValCol =: ([: ". [: > _2 { {) :: 0:

getVal =: 3 : 0
  NB. search for the full key in city_sport (e.g. hat;chicago;baseball
  idx =: 0 { (3{."1 city_sport) i. (,: y)
  ret=:''
  if. (idx getCtCol city_sport) > 3 do.
      ret =: 'city_sport';(idx getValCol city_sport)
  end.
  NB. search for city
  idx =: 0 { (2{."1 city) i. (,: 2{."1 y)
  if. (0 = (#ret)) *. (idx getCtCol city) > 3 do.
      ret =: 'city';(idx getValCol city)
  end.
  NB. search for sport, meaning we need the 1st and 3rd value from the key
  idx =: 0 { (2{."1 sport) i. (,: 0 2 { y)
  if. (0 = (#ret)) *. (idx getCtCol sport) > 3 do.
      ret =: 'sport';(idx getValCol sport)
  end.
  NB. search for item overall
  idx =: 0 { (1{."1 item) i. (,: 0 { y)
  if. (0 = (#ret)) *. (idx getCtCol item) > 3 do.
      ret =: 'item';(idx getValCol item)
  end.
  ret
)

smoutput getVal 'hat';'chicago';'baseball'
smoutput getVal 'hat';'chicago';'hockey'
smoutput getVal 'jersey';'chicago';'soccer'
smoutput getVal 'jersey';'chicago';'badmitton'

NB. not enough hats in the city/sport match or city match
smoutput getVal 'hat';'atlanta';'baseball'


Outputs:

   smoutput getVal 'hat';'chicago';'baseball'

┌──────────┬─┐

│city_sport│1│

└──────────┴─┘

smoutput getVal 'hat';'chicago';'hockey'

┌────┬─┐

│city│1│

└────┴─┘

smoutput getVal 'jersey';'chicago';'soccer'

┌─────┬─┐

│sport│3│

└─────┴─┘

smoutput getVal 'jersey';'chicago';'badmitton'

┌────┬─┐

│item│2│

└────┴─┘
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to