質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.07%

  • Swift

    5896questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Swift 配列の中に配列を入れるのではなく,配列の要素だけ追加したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 91

maru.wk

score 22

前提・実現したいこと

配列dataArrayに関数の戻り値である配列の中身の要素だけ追加したいです。
下記のcreateRGB(x1: Int,y1: Int) -> [UInt8]を使用し,戻り値である[r,g,b]を配列dataArrayに追加する際に,dataArray = [[r,g,b]...]ではなく,dataArray = [r,g,b,...]としたいです。

発生している問題・エラーメッセージ

関数の戻り値で配列を指定しており,dataArrayに追加するには,dataArrayを多次元配列とすることしか自分では思いつかなかった。しかし,dataArrayは普通の配列である必要があり,どうすればよいかわからず困っています。

該当のソースコード

class ViewController: UIViewController {
    var dataArray = [UInt8]()
...
override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        do{
            let image = #imageLiteral(resourceName: "IMG_1758").cgImage
            if let data1 = Transformation.init(inputImage: image!, OutSizeX: 3024, OutSizeY: 4032, Theta2: 75.0) {
                for y in 0...4032{
                    for x in 0...3024{
                       dataArray.append(data1.createRGB(x1: x, y1: y))
                    }
                }
            }
        }
    }

//入力画像から出力画像のRGB配列を作成するクラス
    class Transformation {
        //変数の設定
        var outSizeX : Int
        var outSizeY : Int
        var pixelData : Data
        var bytesPerRow : Int
        let bytesPerPixel = 4
        var RGB : [UInt8]
        var theta2 : Double
        var tanTheta : Double
        var dIn : Double
        var fIn : Double
        var dOut : Double
        var fOut : Double
        var InCenterX : Double
        var InCenterY : Double
        var outCenterX : Double
        var outCenterY : Double
        var inputImage1 : CGImage

        var width : Int
        var height : Int


        //変数の初期値を定める
        init? (inputImage: CGImage, OutSizeX : Int, OutSizeY : Int, Theta2 : Double) {
            outSizeX = OutSizeX
            outSizeY = OutSizeY
            pixelData = inputImage.dataProvider!.data! as Data
            bytesPerRow = inputImage.bytesPerRow
            RGB = []
            theta2 = Theta2
            tanTheta = tan(0.5*theta2*(Double.pi)/180)
            dIn = 0.5*sqrt(pow(Double(inputImage.width),2) + pow(Double(inputImage.height), 2))
            fIn = dIn / tanTheta
            dOut = 0.5*sqrt(pow(Double(outSizeX),2) + pow(Double(outSizeY), 2))
            fOut = 2*dOut / M_PI
            inputImage1 = inputImage
            InCenterX = 0.5*Double(inputImage.width)
            InCenterY = 0.5*Double(inputImage.height)
            outCenterX = 0.5*Double(outSizeX)
            outCenterY = 0.5*Double(outSizeY)

            pixelData = inputImage.dataProvider!.data! as Data
            width = inputImage.width
            height = inputImage.height
            bytesPerRow = inputImage.bytesPerRow

            guard outSizeX>0, outSizeY>0 else { return nil }
            }
        //出力画像のRGB配列を作成する関数
        func createRGB(x1: Int,y1: Int) -> [UInt8]{
            //変数の定義
            var yOutX : Double
            var yOutY : Double
            var yOut : Double
            var inPixelI : Int
            var inPixelJ : Int
            var yIn : Double
            var scale : Double
           // var rgb : [UInt8]

            //全ピクセルに対して処理を行う
            for y in 0..<y1{
                for x in 0..<x1{

                  //出力画像の中心座標から任意のピクセルまでの距離
                  yOutX = Double(x) - outCenterX + 0.5
                  yOutY = Double(y) - outCenterY + 0.5
                  yOut = sqrt(pow(yOutX,2) + pow(yOutY,2))


                  //yOutの値から,条件分岐
                  if yOut == 0 {
                  inPixelI = Int(round(InCenterX-0.5))
                  inPixelJ = Int(round(InCenterY-0.5))
                  //求めた入力画像の座標におけるピクセルのRGB情報を,出力画像のピクセルのRGB情報に上書き
                  let pixelInfo: Int = (Int(bytesPerRow) * inPixelJ + inPixelI * 4)
                  let r = UInt8(pixelData[pixelInfo])
                  let g = UInt8(pixelData[pixelInfo+1])
                  let b = UInt8(pixelData[pixelInfo+2])

                    RGB.append(r)
                    RGB.append(g)
                    RGB.append(b)


                    return (RGB)



                  }else {
                  //射影変換を行い,出力画像でのyOutが入力画像ではどのような値になるか調べる
                  yIn = fIn*tan(yOut/fOut)
                  scale = yIn / yOut
                  //yInから,出力画像の任意のピクセルに対応する,入力画像のピクセルの座標を調べる
                  inPixelI = Int(round(yOutX*scale + InCenterX - 0.5))
                  inPixelJ = Int(round(yOutY*scale + InCenterY - 0.5))
                  //入力画像のピクセルのRGB情報を得る

                  if (inPixelI < Int(x1)) && (inPixelJ < Int(y1)) {
                    let pixelInfo: Int = (Int(bytesPerRow) * inPixelJ + inPixelI * 4)
                    let r = UInt8(pixelData[pixelInfo])
                    let g = UInt8(pixelData[pixelInfo+1])
                    let b = UInt8(pixelData[pixelInfo+2])

                    RGB.append(r)
                    RGB.append(g)
                    RGB.append(b)

                    return RGB

                  }else {
                    let y:UInt8 = 0
                    let r = UInt8(0)
                    let g = UInt8(0)
                    let b = UInt8(0)

                    RGB.append(r)
                    RGB.append(g)
                    RGB.append(b)
                    return RGB

                  }
          }
        }
            return ([0])
        }


}

試したこと

戻り値をタプルとしたり,多次元配列を普通の配列に直せないか調べたのですがうまくいきませんでした。

補足情報(言語/FW/ツール等のバージョンなど)

swift3.0

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

配列に要素を追加するため機能には、appendメソッドのように追加すべき要素を一つ指定するものだけでなく複数の要素(つまり配列)どうしを連結させることもできます。

var da: [Int] = [1, 2]
let a1: [Int] = [3, 4]

da += a1
print(da)    // [1, 2, 3, 4]

こうした機能は「swift 配列 連結」といったそれらしいキーワードを指定して検索すれば大抵見つけられると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/12 12:42

    連結ということが可能なのですね!霧が晴れた気分です!
    これからやってみます。ありがとうございました。

    キャンセル

  • 2018/01/12 12:44

    連結、流行ってるんでしょうかw
    https://teratail.com/questions/108605

    キャンセル

  • 2018/01/12 12:53

    すみません。for文のループの中で増えていく配列を連結させるのはどうすれば良いのでしょうか?;

    キャンセル

  • 2018/01/12 12:53

    まあ・・・あるあるな質問はどうしても重なるということなのでしょうw
    teratailで見つけられるぐらいなら普通にググれば見つかるはずですから、どういうキーワードを指定するか最初はわからないという点が一つの壁なのだろうと思います。

    適当にあたりを付けて「swift 配列 くっつける」でもヒットするかも知れません!やっているうちにだんだんしかるべき「用語」がわかってくると思いますが、そうなれば検索もやりやすくなるだろうと思います。

    キャンセル

  • 2018/01/12 12:55

    for ループの中でもそうでなくても同じで大丈夫と思いますよ。肝心な点は配列変数を更新するのでletとはかけず、varで宣言しなければならない点とか配列の要素の型を合わせるといった点だと思います。そこさえ押さえておけばその変数がアクセスできる場所ならどこででも自由に
    dataArray += くっつけたいもの
    と書けますよ。

    キャンセル

  • 2018/01/12 13:48

    すみません。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.07%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Swift

    5896questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています