I am trying to write an iterator for a 2D array. The following is what I have come up with.
def rowsTest() {
val array = Array(
Array(9, 11, 4, 89),
Array(7, 62, 34, 2),
Array(3, 4, 5, 12),
Array(13, 4, 5, 12),
Array(3, 24, 5, 12),
Array(3, 4, 35, 12)
)
def rows: Iterator[Iterator[Int]] = {
new Iterator[Iterator[Int]] {
private var rowIndex = 0
def hasNext: Boolean = rowIndex < 6
def next: Iterator[Int] = {
val rowIterator = new Iterator[Int] {
private var columnIndex = 0
def next: Int = {
val p = array(columnIndex)(rowIndex)
columnIndex += 1
println("ColIndex = "+ columnIndex.toString)
p
}
def hasNext: Boolean = columnIndex < 4
}
rowIndex += 1
println("RowIndex = "+ rowIndex.toString)
rowIterator
}
}
}
for(row <- rows; elem <- row)
println(elem)
}
The above code when run skips the first row, and also gives an ArrayIndexOutOfBoundsException when all elements have been printed. Can you help me figure out where I've gone wrong?
Thank you,
Siddharth Raina.
How about the following code?
val array = Array(Array(1,2,3),Array(4,5,6),Array(7,8,9))
array.view.flatten.iterator
It works, as tested in REPL. Though I don't know if I achieve what I intended with "view". Any comments are welcome.
Edit
I forgot the author wanted a nested iterator.
array.iterator.map(_.iterator)
This certainly works without the "view" and without overhead.
I can't tell from your code what you actually want to do.
If you want traverse your array with iterators of iterators, there's already an easy way to do it:
val a2d = Array.tabulate(4,4)((i,j)=>4*i+j)
a2d.iterator.map(_.iterator)
And if you decide you want a single iterator, you can do that too:
a2d.iterator.flatMap(_.iterator)
If you want to traverse columns even though the array is in row-major order, then you have a little more work to do (which I think is what you were trying to do, but you mixed up your array indices, and maybe some other things):
def iterateColumns(aai: Array[Array[Int]]) = new Iterator[Iterator[Int]] {
private[this] var j = -1
private[this] val shortest = if (aai.length==0) 0 else aai.map(_.length).min
def hasNext = j+1 < shortest
def next = {
j += 1
new Iterator[Int] {
private[this] var i = -1
def hasNext = i+1 < aai.length
def next = {
i += 1
aai(i)(j)
}
}
}
}
Now you can
scala> for (row <- a2d.iterator.map(_.iterator)) println(row.mkString(" "))
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
scala> for (col <- iterateColumns(a2d)) println(col.mkString(" "))
0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15
(You also ought to be able to do a2d.view.transpose.iterator.map(_.iterator) to avoid making a copy, but unfortunately it doesn't look like this works the way you'd hope in 2.8.1.)
If you want to do it handmade in an imperative style:
def rowsTest() {
val array = Array(
Array(9, 11, 4, 89),
Array(7, 62, 34, 2),
Array(3, 4, 5, 12),
Array(13, 4, 5, 12),
Array(3, 24, 5, 12),
Array(3, 4, 35, 12)
)
def rows: Iterator[Iterator[Int]] = {
new Iterator[Iterator[Int]] {
private var rowIndex = 0
def hasNext: Boolean = rowIndex < 6
def next: Iterator[Int] = {
// fix row index for inner iterator
val rowIdx = rowIndex
val rowIterator = new Iterator[Int] {
private var columnIndex = 0
def next: Int = {
// swap indices!!!
val p = array(rowIdx)(columnIndex)
columnIndex += 1
println("ColIndex = " + columnIndex.toString)
p
}
def hasNext: Boolean = columnIndex < 4
}
rowIndex += 1
println("RowIndex = " + rowIndex.toString)
rowIterator
}
}
}
for (row <- rows; elem <- row)
println(elem)
}
but the
val rows: Iterator[Iterator[Int]] = array.iterator.map(_.iterator)
of ziggystar is still better because its work with non rectangular 2D-arrays too and is more consice and "scalaish".
Related
I have 2d Array which is declared like that init_ : Array[Array[Int]]
In this 2d array, i can only have "1","2" or "3".
I'm looking to print something different when i iterate on these elements, something like that :
override def toString = {
val c = init.map(_.clone);
c match{
case 1 => ret = "one"
case 2 => ret = "two"
case 3 => ret = "three"
}
ret
}
I'm beginning in Scala so please, be indulgent
Here is my 2d arrays :
val tab = $(
$(1, 2, 3,
$(1, 2, 3,
$(1, 2, 3)
I've imported things like that : import scala.{Array => $};
Thanks
Example to iterate a two 2D array and do pattern matching
import scala.{Array => $}
val tab = $(
$(1, 2, 1),
$(1, 2, 2),
$(3, 2, 3),
$(4, 2, 4))
val rowsSize = tab.length
val columnsSize = tab(0).length
for (i <- 0 to rowsSize - 1; j <- 0 to columnsSize - 1) {
tab(i)(j) match {
case 1 => println("one")
case 2 => println("two")
case 3 => println("three")
case x => println(x)
}
}
I'm brand new to flutter and dart. I've searched google and all I can find is how to make 1d lists in flutter. I need a chart of values.
Specifically I need a row 12 long and a column 31 long filled with ascending numbers
1, 32, 63,
2, 33, 64,
3, 34, 65, etc....
thanks!
int row = 3;
int col = 4;
var twoDList = List.generate(row, (i) => List(col), growable: false);
//For fill;
twoDList[0][1] = "deneme";
print(twoDList);
// [[null, deneme, null, null], [null, null, null, null], [null, null, null, null]]
Your 2D list having 3 rows and 4 columns.
Declare and initialize a matrix x having m rows and n columns, containing real numbers.
var x = new List.generate(m, (_) => new List(n));
You can use smart_arrays_numerics package...
look at this..
https://pub.dev/packages/smart_arrays_numerics
else you should use nested list.
List<List<int>>
and create your list with generator
To get exactly what you want, you could use double List.generate, i.e.:
const cols = 31;
const rows = 12;
final array = List.generate(rows,
(i) => List.generate(cols + 1, (j) => i + j * cols + 1, growable: false),
growable: false);
array.forEach((row) {
print(row);
});
// [1, 32, 63, ...
// [2, 33, 64, ...
// [3, 34, 65, ...
// ...
There is also List.filled, where you can fill the array with some initial value when created. The following init the 2d array with 0s.
final array = List.generate(rows + 1, (i) => List.filled(cols + 1, 0, growable: false), growable: false);
To declare and initialize the array 2D in the dart, you can use:
List<List<int>> a =
[
[10, 2, 4, 6, -2],
[ 1, -16, 6, -2, -5],
[ 0, 3, 10, -5, 1],
[ 0, -4, 1, 18, 2],
[ 3, 1, 2, 2, -14],
];
#vahab
so would I do
final int NROWS = 12, NCOLS = 31;
List<Float64List> matrix = List(NROWS);
for (int i = 0; i < 373; i++) {
Float64List row = Float64List(NCOLS);
for (int k = 0; k < NCOLS; k++) { //I dont know what this does
row[k] = double.parse("$i.$k");
}
matrix[i] = row;
}
I would use a nested collection-for:
const maxRows = 31;
const maxColumns = 12;
var matrix = [
for (var row = 0; row < maxRows; row += 1)
[for (var column = 0; column < maxColumns; column += 1)
1 + row + column * maxRows],
];
Just use this statement i got this same problem, Got resolved
var list1 = List.generate(12,(i) => List.generate(31, (j) =>{Your equation to genearte })));
To initialize a 2d matrix filled with 0 :
List.generate(numberRows, (_) => List.filled(numberColumns, 0));
This is the solution I had tried but It was in the order of O(n^2) so didn't passed the test result
func sortArrayByValueAndByFrequency(nums : [Int]) {
var countDict = [Int : Int]()
var count = Int()
var values = Int()
var output = [Int]()
for index in 0 ..< nums.count {
for index2 in 0 ..< nums.count{
if nums[index2] == nums[index] {
values = nums[index2]
count += 1
}
}
countDict[values] = count
count = 0
}
let sortedByKey = countDict.sorted { ($0.key < $1.key)}
let sortedByValue = sortedByKey.sorted { ($0.value < $1.value)}
for (k,v) in sortedByValue {
for _ in 1 ... v {
output.append(k)
}
}
output.forEach { (orderedNumber) in
print(orderedNumber)
}
}
Example input/output:
Example array = [1,1,2,3,4,5,5,6,7,7,7,8,9,9,9,20,25,21,20]
Expected output = [2,3,4,6,8,21,25,1,1,5,5,20,20,7,7,7,9,9,9]
example 2 = [1,2,3,4,4,3,3]
output = [1,2,4,4,3,3,3]
This question was asked to me on HackerRank
First determine the number of occurrences of each value (O(n)),
then sort the values, with the number of occurrences as the
first sort criterion, and the value itself as the second
sort criterion (O(n log(n))). The sorting is conveniently done
with a tuple-comparison (compare Swift - Sort array of objects with multiple criteria):
let array = [1,1,2,3,4,5,5,6,7,7,7,8,9,9,9,20,25,21,20]
let countDict = array.reduce(into: [Int:Int]()) {
$0[$1, default: 0] += 1
}
let sorted = array.sorted(by: {
(countDict[$0]!, $0) < (countDict[$1]!, $1)
})
print(sorted)
// [2, 3, 4, 6, 8, 21, 25, 1, 1, 5, 5, 20, 20, 7, 7, 7, 9, 9, 9]
This question already has answers here:
Find min / max value in Swift Array
(16 answers)
Closed 1 year ago.
I am writing an algorithm to find the lowest number in an array however my print statement keeps saying that the lowest number is 0. I have the following:
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
func findMin(numbers: NSArray) {
var minValue = numbers[0]
var isSmallest: Bool
for i in 0...numbers.count {
isSmallest = true
for j in 0...numbers.count {
if i > j {
isSmallest = false
}
}
if isSmallest {
minValue = i
}
}
print("Smallest value in the list is \(minValue)")
}
findMin(numbers: list as NSArray)
My print statement returns as:
"Smallest value in the list is 0\n"
I feel like the algorithm is correct. Any ideas?
EDIT: Answered my own question
I was iterating over indices and not actual values. Thanks to one of the users in the comments. The correct code should be:
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
func findMin(numbers: NSArray) {
var minValue = numbers[0]
var isSmallest: Bool
for i in list {
isSmallest = true
for j in list {
if i > j {
isSmallest = false
}
}
if isSmallest {
minValue = i
}
}
print("Smallest value in the list is \(minValue)")
}
findMin(numbers: list as NSArray)
Simply
let list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
let minValue = list.min()
For logic use try this
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
var minValue = list[0]
for num in list {
minValue = (num < minValue) ? num : minValue
}
print("Smallest value in the list is \(minValue)")
For direct get min value by property
let list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
let minValue = list.min()
Or you could just use
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
list.min() // returns 2
If you'd like to find the min value without an extra loop, try this:
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
func findMin(numbers: NSArray) {
var minValIdx = 0
var minValue = numbers[0] as! Int
for i in 1..<numbers.count {
if (numbers[i] as! Int) < minValue {
minValue = numbers[i] as! Int
minValIdx = i
}
}
print("Smallest value in the list is \(minValue)")
}
findMin(numbers: list as NSArray)
You can use this code in Swift for manual algorithm:
let list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
var smallest = list[0]
for item in list {
if (item < smallest) {
smallest = item
}
}
print("smallest number is: \(smallest)")
And if you want Swift to do the hard work then use this:
let smallest = list.min()
print("smallest number is: \(smallest)")
here it is your solution
let numbers = [1, 6, 3, 9, 4, 6]
let min = minElement(numbers) // 1
let position = find(array, min)// it will return index
Just to throw a few more options out there, assuming you have to actually show some logic:
func min<T:Comparable>(_ elements:[T]) -> T? {
guard let first = elements[0] else {
return nil
}
return elements.reduce(first, min)
}
print(min(list))
or put it in an extension, this is essentially the definition of Array.min
extension Array where Element : Comparable {
func smallest() -> Element? {
guard let first = self.first else {
return nil
}
// Use 'Swift.min' to get to the global function since Array
// already has a min function
return reduce(first, Swift.min)
}
}
print(list.smallest())
You can use this code:
it is in C#
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
int minVal = list[0];
for (int i = 1; i < list.Length; i++)
{
if (list[i] < minVal)
{
minVal = intArray[i];
}
}
To find the minimum element in the sequence, Swift 3 have an istance method called min():
var list = [5, 4, 3, 5, 2, 50, 8, 10, 300]
let minElem = list.min()
If the sequence has no elements, returns nil.
This method can be used also for a list of floats:
let heights = [67.5, 65.7, 64.3, 61.1, 58.5, 60.3, 64.9]
let minHeight = heights.min()
You can find the official document referece here
I tried to copy it to array, but I can't accept two (Sets) parameters
def subset(a:Set[Int],b:Set[Int]):Boolean={
var x = new Array[Int](a.size)
var y = new Array[Int](b.size)
}
or can you explain how to recieve two arrays as parameter?
def main(args: Array[String]): Unit = {
val a = Set(2,3,4,5,6)
val b = Set(2,3,4,5)
var x = new Array[Int](a.size)
var y = new Array[Int](b.size)
i wish to put x and y to function subset and do same but not by Set
You can transform Set to Array or Array to Set:
scala> val array = Array(1, 3, 5)
array: Array[Int] = Array(1, 3, 5)
scala> array.toSet
res0: scala.collection.immutable.Set[Int] = Set(1, 3, 5)
scala> val set = Set(7, 3, 8)
set: scala.collection.immutable.Set[Int] = Set(7, 3, 8)
scala> set.toArray
res1: Array[Int] = Array(7, 3, 8)
If you want a program to take a collection of Ints as a command-line argument, you'll have to parse a string:
object Test extends App {
val x: Array[Int] = args(0).split(",").map{ _.toInt }
val y: Array[Int] = args(1).split(",").map{ _.toInt }
println("x: " + x.mkString("Array(", ", ", ")"))
println("y: " + y.mkString("Array(", ", ", ")"))
}
Usage:
>scala Test "1,2,3" "10,0,-5"
x: Array(1, 2, 3)
y: Array(10, 0, -5)