Logo

Programming-Idioms

This language bar is your friend. Select your favorite languages!

Idiom #20 Return two values

Implement a function search which looks for item x in a 2D matrix m.
Return indices i, j of the matching cell.
Think of the most idiomatic way in the language to return the two values at the same time.

function search(m, x)
   for i,v1 in ipairs(m) do
      for j,v2 in ipairs(v1) do
         if v2 == x then return i,j end
      end
   end
end
type Matrix is array (Positive range <>, Positive range <>) of Integer;

function Search (M : Matrix; X : Integer; I, J : out Integer) return Boolean is
begin
   for K in M'Range (1) loop
      for L in M'Range (2) loop
         if M (K, L) = X then
            I := K;
            J := L;
            return True;
         end if;    
      end loop;
   end loop;

   return False;
end Search;
#include <string.h>
#include <stdlib.h>
void search(void ***m,void *x,size_t memb_size,int len_x,int len_y,int *i,int *j)
{
	typedef void *m_type[len_x][len_y];
	m_type *m_ref=(m_type*)m;

	for(*i=0;*i<len_x;*i+=1)
	{
		for(*j=0;*j<len_y;*j+=1)
		{
			if(!memcmp((*m_ref)[*i][*j],x,memb_size))
			{
				return;
			}
		}
	}
	*i=*j=-1;
}
module Arr = Bigarray.Array2

let search array value =
	let x_max = Arr.dim1 array in
	let y_max = Arr.dim2 array in
	let rec loop x y = 
		(* End of array *)
		if x = x_max then
			raise Not_found
		(* End of row, go to next *)
		else if y = y_max then
			loop (x+1) 0
		else 
			(* If found, return it *)
			if array.{x,y} = value then
				(x,y)
			(* Otherwise go to next col *)
			else
				loop x (y+1)
	in
	loop 0 0





		
  (defn find-in-2d-matrix [m x]
    (for [i (range (count m))
          j (range (count (first m)))
          :when (= x (-> m (nth i) (nth j)))]
      [i j]))
#include <utility>
template<typename T, size_t len_x, size_t len_y>
std::pair<size_t, size_t> search (const T (&m)[len_x][len_y], const T &x) {
    for(size_t pos_x = 0; pos_x < len_x; ++pos_x) {
        for(size_t pos_y = 0; pos_y < len_y; ++pos_y) {
            if(m[pos_x][pos_y] == x) {
                return std::pair<size_t, size_t>(pos_x, pos_y);
            }
        }
    }

    // return an invalid value if not found
    return std::pair<size_t, size_t>(len_x, len_y);
}
bool _search(const Matrix& _m, const float _x, size_t* const out_i, size_t* const out_j) {
  for (size_t j = 0; j < _m.rows; j++) {
    for (size_t i = 0; i < _m.cols; i++) {
      if (_m.at(i, j) == _x) {
         *out_i = i;
         *out_j = j;
         return true;
      }
    }
  }
  return false;
}
(int, int) Search(int[,] m, int x)
{
    for (var i = 0; i <= m.GetUpperBound(0); i++)
        for (var j = 0; j <= m.GetUpperBound(1); j++)
            if (m[i, j] == x)
                return (i, j);

    return (-1, -1);
}
import std.typecons;
auto search(int[][] m, int x)
{
	foreach (i, row; m)
	{
		foreach (j, cell; row)
		{
			if (cell == x)
				return tuple(i, j);
		}
	}
}
class Position {
  int i, j;
  Position(this.i, this.j);
}
Position search(List<List> m, x) {
  for (var i = 0; i < m.length; i++) {
    var line = m[i];
    for (var j = 0; j < line.length; j++) {
      if (line[j] == x) {
        return new Position(i, j);
      }
    }
  }
  return null;
}
def search(m, x) do
  Enum.reduce_while(m, {0, 0}, fn list, {index, _inner_index} ->
    {found?, inner_index} =
      Enum.reduce_while(list, {false, 0}, fn item, {_found?, acc} ->
        if x == item, do: {:halt, {true, acc}}, else: {:cont, {false, acc + 1}}
      end)

    if found?, do: {:halt, {index, inner_index}}, else: {:cont, {index + 1, inner_index}}
  end)
end
-spec search(T, [[T]]) -> {pos_integer(), pos_integer()}.
search(X, M) -> search(X, M, 1).

search(_, [], _) -> throw(notfound);
search(X, [R|Rs], RN) ->
  case search_row(X, R) of
    notfound -> search(X, Rs, RN+1);
    CN -> {RN, CN}
  end.

search_row(X, Row) -> search_row(X, Row, 1).

search_row(_, [], _) -> notfound;
search_row(X, [X|_], CN) -> CN;
search_row(X, [_|Elems], CN) -> search_row(X, Elems, CN+1).
function search(m,x)
  integer, dimension(:,:), intent(in) :: m
  integer, intent(in) :: x
  integer, dimension(2) :: search
  search = findloc(x,m)
end function search
func search(m [][]int, x int) (bool, int, int) {
	for i := range m {
		for j, v := range m[i] {
			if v == x {
				return true, i, j
			}
		}
	}
	return false, 0, 0
}
search x m = head [ (i, j) | (i, r) <- zip [0..] m,
                             (j, c) <- zip [0..] r, c == x]


let search = (x, m) => {
    let i, j, M = m.length, N
    for (i = 0; i < M; ++i) {
        N = m[i].length
        for (j = 0; j < N; ++j)
            if (m[i][j] == x)
                return [i, j]
    }
    return
}
function search(m, x) {
    for (var i = 0; i < m.length; i++) {
        for (var j = 0; j < m[i].length; j++) {
            if (m[i][j] == x) {
                return [i, j];
            }
        }
    }
    return false;
}
record Z(int a, int b) {}
<T> Z search(T x, T m[][]) {
    int i, j, M = m.length, N;
    for (i = 0; i < M; ++i) {
        N = m[i].length;
        for (j = 0; j < N; ++j)
            if (m[i][j] == x)
                return new Z(i, j);
    }
    return null;
}
static class Position{
	int i;
	int j;
}

Position search(int[][] m, int x){
	for(int i=0;i<m.length;i++)
		for(int j=0;j<m[i].length;j++)
			if(m[i][j] == x){
				Position pos= new Position();
				pos.i = i;
				pos.j = j;
				return pos;
			}
	return null;
}
fun search(m: Array<Array<Int>>, x: Int): Pair<Int, Int>? {
    m.forEachIndexed { i, row ->
        row.forEachIndexed { j, value ->
            if (value == x) {
                return Pair(i, j)
            }
        }
    }
    return null
}
(defun mysearch (x m)
  (loop for i below (array-dimension m 0)
        do (loop for j below (array-dimension m 1)
                 when (eql x (aref m i j))
                 do (return-from my-search
                                 (values i j)))))
@import Foundation;
NSIndexPath *search(NSArray *m,id x) {
  NSUInteger j,i;
  for (i=0;i<m.count;i++) {
    if ((j=[m[i] indexOfObject:x])!=NSNotFound)
      return [NSIndexPath indexPathWithIndexes:&i length:2];
  }
  return nil;
}
function search($x, array $m): ?array
{
    for ($j = 0; $j < count($m); $j++) {
        if (($i = array_search($x, $m[$j])) !== false) {
            return [$i, $j];
        }
    }

    return null;
}
procedure search(m:T2dMatrix; x:TElement; out i,j:integer);
begin
   for i := 0 to high(m) do
	for j := 0 to high(m[i]) do
            if m[i,j] = x then
               exit;
   i := -1;
   j := -1;
end;
sub search {
   my ($x, $m) = @_;
   while ( ($k1,$v1) = each @$m ) {
      while ( ($k2, $v2) = each @$v1 ) {
           return $k1, $k2 if $v2 == $x;
      }
   }
}
def search(m, x):
    for idx, item in enumerate(m):
        if x in item:
            return idx, item.index(x)
def search(x, m):
    for i, M in enumerate(m):
        for j, N in enumerate(M):
            if N == x: return (i, j)
def search(m, x)
  m.each_with_index do |row, i|
    row.each_with_index do |value, j|
      return i, j if value == x
    end
  end
  nil
end
fn search<T: Eq>(m: &Vec<Vec<T>>, x: &T) -> Option<(usize, usize)> {
    for (i, row) in m.iter().enumerate() {
        for (j, column) in row.iter().enumerate() {
            if *column == *x {
                return Some((i, j));
            }
        }
    }

    None
}
def search[T](m: Iterable[Iterable[T]], x: T): Option[(Int, Int)] = {
  for ((row, i) <- m.view.zipWithIndex; (column, j) <- row.view.zipWithIndex if column == x)
    return Some((i, j))
  None
}

New implementation...
< >
programming-idioms.org