このエントリーをはてなブックマークに追加

2016年12月31日土曜日

Swift filter, map, reduceメソッド

 こんにちは、Hiroです。久しぶりにiOSアプリをやることになり四苦八苦しています。
 さて、本日はRuby on Railsでは馴染み深いメソッドのSwift版を紹介したいと思います。


配列(Array)のfilter, map, reduce


配列に関して便利メソッドを3種類紹介します。先ずは、以下の例で操作対象となる配列を宣言しておきます。
// Array
var numbers: [Int] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

filter

クロージャで指定した条件を満たす、新しい配列を返却します。
例として、2の倍数を取得する処理を記述します。
let evenNumbers: [Int] = numbers.filter { (value: Int) -> Bool in
    return value % 2 == 0
}
print(evenNumbers)
// => [0, 2, 4, 6, 8]
上記のようにクロージャを渡すのですが、第一引数に「$0」でアクセスでき、下記のように簡略にすることもできます。
let evenNumbers: [Int] = numbers.filter { $0 % 2 == 0 }
print(evenNumbers)
// => [0, 2, 4, 6, 8]

map

配列の1つ1つにクロージャで指定した処理を行った配列の結果を返却します。
例として、1つ1つの要素を2倍にする処理を記述します。
let doubleNumbers: [Int] = numbers.map { (value: Int) -> Int in
    return value * 2
}
print(doubleNumbers)
// => [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
簡略式も下記に記載します。
let doubleNumbers: [Int] = numbers.map { $0 * 2 }
print(doubleNumbers)
// => [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

reduce

要素のたたみ込みをするためのメソッドです。要素をまとめて一つにする場合などで利用できます。 例として、要素の合計値を取得する処理を記述します。
let totalNumber = numbers.reduce(0) { (total: Int, value: Int) -> Int in
    total + value
}
print(totalNumber)
// => 45
簡略式も下記に記載します。
let totalNumber = numbers.reduce(0) { $0 + $1 }
print(totalNumber)
// => 45


辞書(Dictionary)のfilter, map, reduce


辞書に関しても上記の「filter」「map」「reduce」のメソッドは使えますので、簡略式ですが、こちらも記載しておきます。先ずは、例で操作対象となる辞書を宣言しておきます。
// Dictionary
var dictNumbers = ["zero":0, "one": 1, "two": 2, "three": 3 , "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 8, "nine": 9]

filter

Dictionaryのため、順序保証がないのと、返却値はタプルの配列になっています。
let evenDictNumbers = dictNumbers.filter { $0.1 % 2 == 0 }
print(evenDictNumbers)
// => [("four", 4), ("zero", 0), ("two", 2)] 

map

こちらもタプルとしていますが、辞書で返却したい場合が普通のケースですので、そん場合、次で紹介する「reduce」のやり方がよいでしょう。
let doubleTupleNumbers = dictNumbers.map { ($0.0, $0.1 * 2) }
print(doubleTupleNumbers)
// => [("three", 6), ("one", 2), ("nine", 18), ("seven", 14), ("four", 8), ("five", 10), ("zero", 0), ("six", 12), ("eight", 16), ("two", 4)]

reduce

let doubleDictNumbers = dictNumbers.reduce([String: Int]()) { var varDict = $0; varDict[$1.0] = $1.1 * 2; return varDict}
print(doubleDictNumbers)
// => ["three": 6, "one": 2, "nine": 18, "seven": 14, "four": 8, "five": 10, "zero": 0, "six": 12, "eight": 16, "two": 4]
上記で、注意点としては、一度「$0」を「varDict」変数に代入しているところです。これは、「$0」がイミュータブルな変数だからです。
そのため、下記ではエラーとなります。
let doubleDictNumbers = dictNumbers.reduce([String: Int]()) { $0[$1.0] = $1.1 * 2; return $0}
// =>Cannot assign through subscript: '$0' is immutable


いかがでしたでしょうか。Ruby on Railsではおなじみのメソッドですが、少しSwiftならではの制約があります。ただ、とても可読性が高く、便利なメソッドなのでどんどん利用してみようと思います。

2016年12月30日金曜日

ObjectMapperでJSONのネスト配列に対応する方法

こんにちは、onukiです。

私はSwiftでJSONを取り扱う際に、
ObjectMapperを使用してるのですが
今回は読み込むJSONにネスト配列がある場合の使い方を書いていこうと思います。

ObjectMapperとは

ObjectMapperとはJSONデータをモデルに変換する処理を
簡単に扱えるライブラリです。

使い方

今回、読み込むJSONは以下のようなネスト配列が含まれているものを使用します。
{
    "id": 1,
    "name": "user1",
    "address": "hoge",
    "photos": [
    {
    "id": 1,
    "name": "photo1"
    },
    {
    "id": 2,
    "name": "photo2"
    }
    ]
}

ObjectMapperはMappableプロトコルをモデルクラスに実装し使用するのですが
今回はネスト配列に対応するために2つ作成します。
struct User: Mappable {
    var id = 0
    var name = ""
    var address = ""
    var photos: [Photo] = []
    
    init?(map: Map){}
    mutating func mapping(map: Map) {
        id <- map["id"]
        name <- map["name"]
        address <- map["address"]
        photos <- map["photos"]
    }
}
struct Photo: Mappable {
    var id = 0
    var name = ""
    
    init?(map: Map){}
    mutating func mapping(map: Map) {
        id <- map["id"]
        name <- map["name"]
    }
}

JSONからモデルに変換するのには以下のように取得します。
let user: User = Mapper().map(JSONString: jsonString)!
print(user.name) // => "user1"

そして、userのphotos配列から0番目のデータを取得したい際にはこのように取得します。
let photo: Photo = user.photos[0]

これでObjectMapperでJSONのネスト配列を読み込み、扱うことが出来ました。

2016年12月29日木曜日

はじめの一歩 -Rails ActiveRecord編- INSERT


どうも、はじめです。

前回はActiveRecordについて書いてみました。
はじめの一歩 -Rails ActiveRecord編- 序章
今回はActiveRecordのデータの保存(create,new)について
描いてみようと思います。


データを保存したい場合


ActiveRecordにてDBにデータを保存する場合は
createまたは、newを使用します。
それぞれの記述方法は以下のようになります。

create
User.create(name: '山田', mail: 'xxx@xxx.xxx')
new
user = User.new(name: '山田', mail: 'xxx@xxx.xxx')
user.save()

#  または
user = User.new()
user.name = '山田'
user.mail = 'xxx@xxx.xxx'
user.save()
上記のように記述することでusersテーブルに対し、
name: 山田
mail: xxx@xxx.xxx
というレコードがinsertされます。


例外を発生させたい場合


create,new共に「!」をつけるだけでinsertに失敗した際に例外を発生させてくれます。

create

User.create!(...)

new

user = User.new(...)
・
・
user.save!


createとnewの違い


違いとしてあげられるものはDBにinsertをするタイミングです。
それぞれ以下のタイミングでDBへinsertされます。
create -> createメソッドの実行時
new -> saveメソッドの実行時

ちなみに、
以下のようにsaveメソッドを複数回記述しても
insertされるのは最初の一度のみとなります。
user = User.new(...)
・
・
user.save # ←ここでのみinsertされる
user.save # 何もinsertされない
user.save # 何もinsertされない
試してみたところ2回目以降のinsertは何もinsertされませんが、
返り値はtrueが返却されました。


最後に


createを実行した際は裏でnewとsaveを順番に行なっているだけなので、
結果やっていることは変わりません。
なので、インスタンスを生成するタイミングで登録に必要な値が全て揃っている場合はcreate。
それ以外の場合。
例として、
・任意のタイミングでsaveしたい。
・インスタンスの生成後に何かの処理をしたい。
・特定の条件でのみ登録するカラムが存在する。
等の理由がある場合はnewを使用するといった形になるのではないかと思いました。


次回


次回は更新(update)について書いていきたいと思います。

2016年12月28日水曜日

サイバーセキュリティ入門 前編


こんにちは、h_ono_222です。
今回のドトール会はで「サイバーセキュリティ入門: 私たちを取り巻く光と闇」の1. インターネットの仕組みについて発表しました。

はじめに、本書の構成について簡単に説明すると、本書では六つのテーマについて書かれています。
テーマはそれぞれ、

  1. インターネットの仕組み(プロトコル、ルーティング)
  2. 暗号の世界に飛び込もう(AES、RSAなどの暗号化方式)
  3. インターネットとセキュリティ(VPN、電子証明書)
  4. インターネットにおけるサイバー攻撃(DOSを始めとした攻撃手法)
  5. ハードウェアとソフトウェア(ハードウェアによる暗号化とその解析)
  6. 私達を取り巻くセキュリティ(法律)

となっています。
本書は全体を通して、専門用語をわかりやすい例えで説明しており、また、インターネットの基礎的な知識も得ることができることから、
コンピュータに興味がある高校生などにもオススメの一冊となっております。

1. インターネットの仕組みでは、まず電話とインターネットの違いから説明し、
インターネットが耐障害性の強いネットワークであることを示しています。

そして、通信を行うための約束事(プロトコル)に関して、セオリー通りOSI参照モデルの各層について、その役割を説明しています。

この部分を読んでおくと、インターネットの基礎的な部分が理解できると思います。

次回は4と5について発表する予定です。

2016年12月27日火曜日

Railsのバリデーション

この記事は移転しました。
http://re-engines.com/2017/12/08/rails-validation/