覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

「ザッソウ 結果を出すチームの習慣 ホウレンソウに代わる「雑談+相談」」

「ザッソウ 結果を出すチームの習慣 ホウレンソウに代わる「雑談+相談」」 を読んでみました。

ザッソウ 結果を出すチームの習慣

ザッソウ 結果を出すチームの習慣

  • 作者:倉貫義人
  • 発売日: 2019/08/30
  • メディア: Kindle版


内容紹介は以下のようになっています

●「ホウレンソウ」だけではチームは回らない
仕事をする上で、「ホウレンソウ(報告・連絡・相談)」は大切です。
こまめな報告があれば安心でき、
連絡が行き届くことで無駄もなくなり、
相談があることでいち早く問題を解決することができます。
ホウレンソウは社会人にとっての基礎スキルといえます。

ただ、ホウレンソウだけでは、
チームのコミュニケーションが機能しなくなってきています。

近年、チーム間で(とくに、上司と部下の間で)個人的な話がしにくくなっています。
働き方改革によって残業が減り、飲みニケーションや喫煙所での会話も少なくなりました。
ハラスメントに注意しすぎて仕事以外の話もしにくく、
つねに成果を求められているため、短期的な仕事の話が中心になっています。

こうしたコミュニケーションだけでは、
人を、成果を出すための道具としてしか見られなくなり、
やがてチームのモチベーションは下がっていってしまいます。
人としてコミュニケーションがとれる場を、
チームとして継続的に設けることが必要なのです。

●チームを活性化させる「ザッソウ」
具体的にいうと、それはチームにおけるコミュニケーションのあり方を
「ホウレンソウ」のステージから「ザッソウ(雑談・相談)」に上げる、ということです。

ザッソウを通して、メンバー同士が何を考え、
何を感じているのかを共有し、言いたいことを言い合える信頼関係をつくる。
それはチームに心理的安全をもたらし、メンバーのやる気を高めることにもつながります。

それに普段から雑談をしていれば、本当に困ったときに相談しやすくなります。
旧来のホウレンソウだけの状態では、信頼関係ができていないわけですから、
たとえ「いつでも相談していい」と言われていても、なかなか声をかけにくいものです。
つまり話しかける心理的ハードルを下げるためにも、ザッソウは有効なのです。

それだけではありません。新しいアイデアが出ない、専門的な知識がなくて困っている……
そんな問題を解決したいとき、ザッソウでコミュニケーションをとるうちに
価値が生まれることがあります。
ザッソウは、イノベーションにつながるアイデアが生まれ、
チームの生産性を高めることにもつながるのです。


本のカバーには以下のようにザッソウが定義されています。

  • ざっそう【ザッソウ】
    • 「雑談+相談」「雑な相談」
    • 雑談があることで相談がしやすくなり、人間関係が構築されて心理的安全性を高めることができる。
      チームビルディングを成功させるのはホウレンソウではなくザッソウ。


社会人になると、早い段階でまず耳にするであろうホウレンソウ(報・連・相)。
報告、連絡、相談 というのを適切なタイミングでやることを社会人として求められます。
なんとなく、部下が身につけておくべき基本的な姿勢という風に思われます。

が、実際のところ

そもそも「報連相」とは、山種証券(現・SMBCフレンド証券)社長の山崎富治氏が社内で「ほうれんそう運動」を始めたことがきっかけです。

下からの意見をどう吸いあげるか、みんなが働きやすい環境をどう作るか、暖かい人間関係をどう作るか、
少数精鋭で社員一人ひとりに厚く報いるには…と、
つね日ごろ頭を悩ませていたとき思いついたのが、”ほうれんそう”だった。

上司・部下の間で情報が行き来する風通しの良い職場環境を作ろうというスローガンで、部下への情報共有を義務付けるものではありません。

しかし、現在ではなんとなく部下への義務的な要件として浸透しています。

世間一般的に広まった ホウレンソウ ではなく ザッソウ によって
組織内の相互理解が高まる、心理的安全性が生まれる、率直に意見をぶつけ合えることで成果が出せる、
新しいアイデアが生まれる、組織を変える土台になる、、、ということが述べられています。

筆者が関わってきた事例などをベースにザッソウの重要性や必要性が述べられています。
割と薄い本ですが、内容は共感する部分が多いです。
多くの人に読んでもらいたい本です。


以下は私が書籍内で気になった部分の抜粋です。(自分用のメモです)

  • 1on1ミーティング という形で、上司と部下で評価面談と別にお互いに考えていることなどを共有する機会を作っている組織が多くあります。
    この1on1ミーティングこそ、中身はザッソウです。雑談であったり、相談であったり、特に決着をつけなくていいからこそ、気軽に話をすることができます

  • 気軽なフィードバックで仕事の質と速度が向上する

    • マネージャーや上司として困るのは、依頼や指示をした内容とまったく違うものが時間をかけた後に出てくるケースです。
    • 少しずつ確認していくことが手戻りを減らす最善手となります
  • 働きがいと働きやすさが両立したワクワクする職場には、事業を自分事として考えられる人たちがいる活気の良さと、経済的に安心できて家族や自分の時間を持つことができる制度があります。

  • 少なくとも手応えがあることは、働きがいの必須条件といえます。
    それはどのような形であれフィードバックがあることです。
    半年に一度の評価面談や定例会議などを持つことなく、気軽にザッソウしてフィードバックされる気合があればいいのです。

  • 心理的安全性を高める9つの観点

    • チームの目標がはっきりしている
    • 適度に対話しやすい人数である
    • 強みを知り、認め合っている
    • 強みだけでなく、弱みも見せる
    • プライベートなことも共有している
    • 情報がオープンになっている
    • 判断基準と価値観が共有されている
    • リアクションの意識がそろっている
    • 「肯定ファースト」と「NOと言うこと」
  • 自分の弱みを隠さないでいられれば、困ったときに気軽にザッソウできるようになるので成果も上げることができています。
    チームの利点は、仲間が集まることで、1人では実現できない挑戦ができることです。一方、弱ったときに助け合うことで、
    1人で潰れてしまわないようにするという利点もあります。そもそも助け合うためには、弱みを見せることは悪いことでは無いのです。

  • フォロワーもある意味でリーダーシップの1つの形態であると主張しています。

  • ザッソウあふれる職場やチームには、明るく穏やかな空気が流れています。
    その雰囲気を生み出しているのは、やはりリーダーの姿勢や人柄によるところが大きくなります。

  • しなやかなマインドセットの人には、人間の基本的な資質は努力次第で伸ばすことができるという信念があります。
    持って生まれた資質は違っていても、その後の努力と経験で伸ばすことができる。
    だから、現時点で足りていない・できていない自分でも認めることができるのです。ですから難しい問題に出会っても粘り強く立ち向かうことができます。

  • 自己組織化とは、もともと自然現象をモデル化した際に使われた表現で、自律的に秩序や構造を作り出す現象のことをいいます。
    それを組織やチームへ適用して考えてみると、組織を構成しているメンバーそれぞれが、場に備わったミッションや目的を達成するために、自律的に考えて行動しつつも相互に助け合い、作用し合っている状態と考えられます。

  • ネットワーク型の情報共有は、メンバー1人ひとりの情報リテラシーが問われます。情報を自ら収集する必要がありますし、その情報の正しさを精査して理解するところは各人に任されるからです。しかし、そうして分散化した方がスピードが速く、新しく価値が生み出される可能性すらあるのです。それはまさしくインターネットの世界で実証されています。

  • 人というのは、どれだけ外部から良い方法を教えたり、指導したところで行動を変えることは難しいものです。それは自分たちのことがわかっていないからです。必要なのは、自分たちのことを知る機会です。自分たちが本当にまずい状態だと思えば改善する意欲もわくでしょう。そうなって、ようやく変わる出発点に立ってくれます。鏡を見ることがなければ、自分の顔が汚れていることには気づかないものです。だから、ふりかえりとは、チームで自分たちの姿を鏡で見る機会でもあるのです。

矩形同士の交差

左下の座標(X, Y) と 右上の座標(X, Y) が 与えられた矩形(長方形)があったとして、

f:id:nini_y:20190829212551p:plain

2つの矩形が与えられて、その矩形同士が以下のように交差(領域が被っているかを)しているか判定したいです

f:id:nini_y:20190829230458p:plain

交差の判定は

Max(矩形1.左下X, 矩形2.左下X) < Min(矩形1.右上X, 矩形2.右上X) かつ Max(矩形1.左下Y, 矩形2.左下Y) < Min(矩形1.右上Y, 矩形2.右上Y)

で、出来ます。(矩形同士の線分が接しているだけの状態は交差とは呼びにくいと思うので、<= ではなく < で判定しています


一応Javaでプログラム書いてみました。
なんか中途半端な気もしますが・・・

/**
 * 矩形を表現するクラス
 */
public final class Rectangle {

    /** 矩形の左下の点のX */
    private final int lBottomX;

    /** 矩形の左下の点のY */
    private final int lBottomY;

    /** 矩形の右上の点のX */
    private final int rTopX;

    /** 矩形の右上の点のY */
    private final int rTopY;

    public Rectangle(int lBottomX, int lBottomY, int rTopX, int rTopY) {
        // そもそも線や点の表現になってしまう場合は矩形とみなさないものとする
        // 左下と右上の位置関係にならない場合も不正とみなす
        if (lBottomX >= rTopX || lBottomY >= rTopY) {
            throw new IllegalArgumentException("Invalid parameter.");
        }

        this.lBottomX = lBottomX;
        this.lBottomY = lBottomY;
        this.rTopX = rTopX;
        this.rTopY = rTopY;
    }

    /**
     * 引数の矩形と2点が交差するかどうかを判定します
     *
     * @param rec 判定対象の矩形
     * @return 交差する場合true, それ以外の場合false
     */
    public boolean hasIntersect2point(Rectangle rec) {
        return Math.max(lBottomX, rec.lBottomX) < Math.min(rTopX, rec.rTopX) &&
                Math.max(lBottomY, rec.lBottomY) < Math.min(rTopY, rec.rTopY);
    }

    /**
     * 2点が交差する場合の交差している領域を表現する矩形を返します
     *
     * @param rec 判定対象の矩形
     * @return 交差している領域を表現する矩形
     */
    public Rectangle intersect2pointRectangle(Rectangle rec) {
        int maxLBottomX = Math.max(lBottomX, rec.lBottomX);
        int maxLBottomY = Math.max(lBottomX, rec.lBottomY);
        int minRTopX = Math.min(rTopX, rec.rTopX);
        int minRTopY = Math.min(rTopY, rec.rTopY);

        if (!hasIntersect2point(maxLBottomX, minRTopX, maxLBottomY, minRTopY)) {
            throw new IllegalStateException("not intersect 2point.");
        }

        return new Rectangle(maxLBottomX, maxLBottomY, minRTopX, minRTopY);
    }

    private boolean hasIntersect2point(int maxLBottomX, int minRTopX, int maxBottomY, int minRTopY) {
        return maxLBottomX < minRTopX && maxBottomY < minRTopY;
    }

    /**
     * 面積を求める
     *
     * @return 面積
     */
    public int area() {
        return (rTopX - lBottomX) * (rTopY - lBottomY);
    }

    @Override
    public String toString() {
        return "Rectangle{" +
                "lBottomX=" + lBottomX +
                ", lBottomY=" + lBottomY +
                ", rTopX=" + rTopX +
                ", rTopY=" + rTopY +
                ", area=" + area() +
                '}';
    }
}


交差していない矩形同士の場合

矩形同士が離れている場合

public class Main {
    public static void main(String[] args) {
        Rectangle rBase = new Rectangle(2, 2, 6, 5);

        Rectangle r1a = new Rectangle(0, 0, 1, 1);

        System.out.println(""rBase.hasIntersect2point(r1a));        
    }
}


出力結果

false

交差の判定が false になっています


矩形同士のある1辺だけが接していて領域としては重なっていない場合

public class Main {
    public static void main(String[] args) {
        Rectangle rBase = new Rectangle(2, 2, 6, 5);

        Rectangle r1b = new Rectangle(6, 3, 9, 8);

        System.out.println(""rBase.hasIntersect2point(r1b));        
    }
}


出力結果

false

2つの矩形のある辺が重なっている場合も、交差の判定は false になっています


交差する矩形同士の場合

public class Main {
    public static void main(String[] args) {
        Rectangle rBase = new Rectangle(2, 2, 6, 5);

        Rectangle r2 = new Rectangle(1, 1, 3, 4);

        System.out.println(rBase.hasIntersect2point(r2));
        System.out.println(rBase.intersect2pointRectangle(r2));
    }
}


出力結果

true
Rectangle{lBottomX=2, lBottomY=2, rTopX=3, rTopY=4, area=2}


public class Main {
    public static void main(String[] args) {
        Rectangle rBase = new Rectangle(2, 2, 6, 5);

        Rectangle r3 = new Rectangle(3, 3, 4, 4);

        System.out.println(rBase.hasIntersect2point(r3));
        System.out.println(rBase.intersect2pointRectangle(r3));
    }
}


出力結果

true
Rectangle{lBottomX=3, lBottomY=3, rTopX=4, rTopY=4, area=1}


public class Main {
    public static void main(String[] args) {
        Rectangle rBase = new Rectangle(2, 2, 6, 5);

        Rectangle r4 = new Rectangle(3, 3, 6, 7);

        System.out.println(rBase.hasIntersect2point(r4));
        System.out.println(rBase.intersect2pointRectangle(r4));
    }
}


出力結果

true
Rectangle{lBottomX=3, lBottomY=3, rTopX=6, rTopY=5, area=6}


交差の判定が true になって、交差した領域の矩形の情報(座標情報, 面積)が出力されます。

jqで基礎的な操作をしてみる

前回、jqコマンドをインストールしました。


基礎的な操作だけ試しておきます。

仮に person.json というファイルの内容が以下のようになっているとします

{ "name": { "first" : "taro", "last": "yamada" }, "age": 20 }


これを整形して表示する場合は以下になります

cat person.json | jq .

出力結果は以下の通りで整形されています。

{
  "name": {
    "first": "taro",
    "last": "yamada"
  },
  "age": 20
}


このJSONから「name」項目を取得したい場合は以下です

cat person.json | jq .name

出力結果は以下の通りで整形されています。

{
  "first": "taro",
  "last": "yamada"
}


「name」の中の 「first」の値だけ取りたいときは以下になります

cat person.json | jq .name

出力結果は以下の通り

"taro"


このやり方が望ましいかわかりませんが以下でもいけますね

cat person.json | jq .name | jq .first

出力結果は以下の通り

"taro"


出力結果を囲んでいるダブルクォートが邪魔な場合は -r オプションをつけます

cat person.json | jq -r .name

出力結果は以下の通り

taro


「name.first」 と 「name.last」 を結合した結果を出力してみます

cat person.json | jq .name | jq -r '.first + " " + .last'

出力結果は以下の通り

taro yamada


少し複雑めなJSONを操作

$ curl -s "http://geoapi.heartrails.com/api/json?method=searchByPostal&postal=1060032" | jq . 
{
  "response": {
    "location": [
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木一丁目",
        "town_kana": "ろっぽんぎ1ちょうめ",
        "x": "139.740991",
        "y": "35.665082",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木二丁目",
        "town_kana": "ろっぽんぎ2ちょうめ",
        "x": "139.737087",
        "y": "35.666974",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木三丁目",
        "town_kana": "ろっぽんぎ3ちょうめ",
        "x": "139.735452",
        "y": "35.663977",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "ç": "六本木四丁目",
        "town_kana": "ろっぽんぎ4ちょうめ",
        "x": "139.733837",
        "y": "35.665489",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木五丁目",
        "town_kana": "ろっぽんぎ5ちょうめ",
        "x": "139.735248",
        "y": "35.658358",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木六丁目",
        "town_kana": "ろっぽんぎ6ちょうめ",
        "x": "139.729932",
        "y": "35.659856",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木七丁目",
        "town_kana": "ろっぽんぎ7ちょうめ",
        "x": "139.726863",
        "y": "35.664751",
        "prefecture": "東京都",
        "postal": "1060032"
      }
    ]
  }
}


上記の中から「town」だけ列挙してみる

curl -s "http://geoapi.heartrails.com/api/json?method=searchByPostal&postal=1060032" | jq .response.location[].town
"六本木一丁目"
"六本木二丁目"
"六本木三丁目"
"六本木四丁目"
"六本木五丁目"
"六本木六丁目"
"六本木七丁目"


当初取得した値の中から 「town」,「x」, 「y」だけのJSONにしたい場合は map 使うと可能です

$ curl -s "http://geoapi.heartrails.com/api/json?method=searchByPostal&postal=1060032" | jq '.response.location | map({town: .town, x: .x, y: .y})'
[
  {
    "town": "六本木一丁目",
    "x": "139.740991",
    "y": "35.665082"
  },
  {
    "town": "六本木二丁目",
    "x": "139.737087",
    "y": "35.666974"
  },
  {
    "town": "六本木三丁目",
    "x": "139.735452",
    "y": "35.663977"
  },
  {
    "town": "六本木四丁目",
    "x": "139.733837",
    "y": "35.665489"
  },
  {
    "town": "六本木五丁目",
    "x": "139.735248",
    "y": "35.658358"
  },
  {
    "town": "六本木六丁目",
    "x": "139.729932",
    "y": "35.659856"
  },
  {
    "town": "六本木七丁目",
    "x": "139.726863",
    "y": "35.664751"
  }
]


まとめ

まとめるほど触ってませんが、まだまだ相当な機能やオプションをjqコマンドは備えています。
もっと使いこなせるようになりたいです。



関連エントリ

HomeBrew で jqをインストールしてみる

jsonデータを整形・絞り込みできるjqコマンドをmacOSにインストールしたかったので、HomeBrewでインストールしてみました。


インストール

以下を実行します。

$ brew install jq


実行時のログは以下の様な感じでした

$ brew install jq
==> Installing dependencies for git: pcre2
==> Installing git dependency: pcre2
==> Downloading https://homebrew.bintray.com/bottles/pcre2-10.32.mojave.bottle.tar.gz
Updating Homebrew...
######################################################################## 100.0%
==> Pouring pcre2-10.32.mojave.bottle.tar.gz
🍺  /usr/local/Cellar/pcre2/10.32: 224 files, 5.5MB
==> Installing git
==> Downloading https://homebrew.bintray.com/bottles/git-2.19.2.mojave.bottle.tar.gz
######################################################################## 100.0%
==> Pouring git-2.19.2.mojave.bottle.tar.gz
==> Caveats
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completions and functions have been installed to:
  /usr/local/share/zsh/site-functions

Emacs Lisp files have been installed to:
  /usr/local/share/emacs/site-lisp/git
==> Summary
🍺  /usr/local/Cellar/git/2.19.2: 1,520 files, 40.1MB
==> Caveats
==> git
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completions and functions have been installed to:
  /usr/local/share/zsh/site-functions

Emacs Lisp files have been installed to:
  /usr/local/share/emacs/site-lisp/git
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
Warning: Aleth (formerly cpp-ethereum) has been removed from Homebrew. Please install binary releases from https://github.com/ethereum/aleth/releases.
==> Auto-updated Homebrew!
Updated 3 taps (homebrew/core, homebrew/cask and ethereum/ethereum).
==> New Formulae

(中略)

==> Renamed Formulae
ark -> velero                              gnatsd -> nats-server                      todolist -> ultralist
confluent-oss -> confluent-platform        php72 -> php@7.2                           transmission -> transmission-cli
gloo-ctl -> glooctl                        resin-cli -> balena-cli
==> Deleted Formulae
apple-gcc42          gdnsd                js-test-driver       pdftoedn             rock                 tomcat@6
at-spi2-atk          gnome-doc-utils      ld64                 percona-server@5.6   ruby@1.8             typesafe-activator
at-spi2-core         go@1.4               libggz               php@5.6              ruby@2.3             varnish@4
cctools              go@1.8               libguess             php@7.0              safe                 whirr
cctools-headers      gradle@2.14          liblastfm            plan9port            scala@2.10           xmoto
compose2kube         gtk-engines          libutf               pldebugger           smlnj                zxing-cpp
cputhrottle          gtk-murrine-engine   lysp                 protobuf@2.5         solr@5.5
dsd                  guile@2.0            minisat              protobuf@2.6         solr@6.6
erlang@18            gv                   monax                pyexiv2              swig@3.04
ffmbc                hyper                node@6               rlvm                 tmux-cssh

==> Installing dependencies for jq: oniguruma
==> Installing jq dependency: oniguruma
==> Downloading https://homebrew.bintray.com/bottles/oniguruma-6.9.3.mojave.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/f0/f00f8c6f8afd8875fed685a9190cb0c5e9b5ceef58ef1e489fb17a42bddc9672?__gda__=exp=1
######################################################################## 100.0%
==> Pouring oniguruma-6.9.3.mojave.bottle.tar.gz
🍺  /usr/local/Cellar/oniguruma/6.9.3: 17 files, 1.3MB
==> Installing jq
==> Downloading https://homebrew.bintray.com/bottles/jq-1.6.mojave.bottle.1.tar.gz
==> Downloading from https://akamai.bintray.com/71/71f0e76c5b22e5088426c971d5e795fe67abee7af6c2c4ae0cf4c0eb98ed21ff?__gda__=exp=1
######################################################################## 100.0%
==> Pouring jq-1.6.mojave.bottle.1.tar.gz
🍺  /usr/local/Cellar/jq/1.6: 18 files, 1MB
==> `brew cleanup` has not been run in 30 days, running now...
Removing: /Users/yuki/Library/Caches/Homebrew/git--2.19.2.mojave.bottle.tar.gz... (15.2MB)
Removing: /Users/yuki/Library/Caches/Homebrew/go--1.11.1.sierra.bottle.tar.gz... (140.5MB)
Removing: /Users/yuki/Library/Caches/Homebrew/icu4c--62.1.sierra.bottle.tar.gz... (25.4MB)
Removing: /Users/yuki/Library/Caches/Homebrew/jenv--0.4.4.tar.gz... (18KB)
Removing: /Users/yuki/Library/Caches/Homebrew/nkf--2.1.4.sierra.bottle.tar.gz... (157.8KB)
Removing: /Users/yuki/Library/Caches/Homebrew/node--11.2.0.sierra.bottle.tar.gz... (13.3MB)
Removing: /Users/yuki/Library/Caches/Homebrew/pcre2--10.32.mojave.bottle.tar.gz... (1.8MB)
Removing: /Users/yuki/Library/Caches/Homebrew/tree--1.8.0.sierra.bottle.tar.gz... (50.5KB)
Removing: /Users/yuki/Library/Caches/Homebrew/yarn--1.12.3.tar.gz... (1.1MB)
Removing: /Users/yuki/Library/Caches/Homebrew/z3-4.7.1.sierra.bottle.tar.gz... (27.3MB)
Removing: /Users/yuki/Library/Caches/Homebrew/openssl-1.0.2o_2.sierra.bottle.tar.gz... (3.7MB)
Removing: /Users/yuki/Library/Caches/Homebrew/gdbm-1.14.1_1.sierra.bottle.tar.gz... (182.5KB)
Removing: /Users/yuki/Library/Caches/Homebrew/gettext-0.19.8.1.sierra.bottle.tar.gz... (7.8MB)
Removing: /Users/yuki/Library/Caches/Homebrew/readline-7.0.3_1.sierra.bottle.tar.gz... (497.3KB)
Removing: /Users/yuki/Library/Caches/Homebrew/python@2-2.7.15.sierra.bottle.tar.gz... (18.3MB)
Removing: /Users/yuki/Library/Caches/Homebrew/wget-1.19.5.sierra.bottle.tar.gz... (1.3MB)
Removing: /Users/yuki/Library/Caches/Homebrew/cmake-3.11.3.sierra.bottle.tar.gz... (11.8MB)
Removing: /Users/yuki/Library/Caches/Homebrew/boost-1.67.0_1.sierra.bottle.tar.gz... (86.6MB)
Removing: /Users/yuki/Library/Caches/Homebrew/linkage.db... (48KB)
Removing: /Users/yuki/Library/Caches/Homebrew/sqlite-3.24.0.sierra.bottle.tar.gz... (1.7MB)
Removing: /Users/yuki/Library/Caches/Homebrew/nodebrew-1.0.0.tar.gz... (26.3KB)
Removing: /Users/yuki/Library/Caches/Homebrew/solidity-0.4.24.tar.gz... (1.1MB)
Removing: /Users/yuki/Library/Caches/Homebrew/portable-ruby-2.3.3_2.leopard_64.bottle.tar.gz... (12.4MB)
Removing: /Users/yuki/Library/Caches/Homebrew/ethereum-1.8.10.sierra.bottle.tar.gz... (64.2MB)
Removing: /Users/yuki/Library/Caches/Homebrew/portable-ruby-2.3.7.leopard_64.bottle.tar.gz... (12.4MB)
Removing: /Users/yuki/Library/Caches/Homebrew/go-1.10.3.sierra.bottle.tar.gz... (102.6MB)
Removing: /Users/yuki/Library/Caches/Homebrew/openssl-1.0.2o_1.sierra.bottle.tar.gz... (3.7MB)
Removing: /Users/yuki/Library/Caches/Homebrew/watch-3.3.15.sierra.bottle.tar.gz... (30.9KB)
Removing: /Users/yuki/Library/Caches/Homebrew/nmap-7.70.sierra.bottle.tar.gz... (7.1MB)
Removing: /Users/yuki/Library/Caches/Homebrew/libunistring-0.9.10.sierra.bottle.tar.gz... (1.4MB)
Removing: /Users/yuki/Library/Caches/Homebrew/ccache-3.4.2.sierra.bottle.tar.gz... (89.8KB)
Removing: /Users/yuki/Library/Caches/Homebrew/libidn2-2.0.5.sierra.bottle.tar.gz... (217.4KB)
Removing: /Users/yuki/Library/Caches/Homebrew/Cask/adoptopenjdk--11.0.1,13.tar.gz... (181.1MB)
Removing: /Users/yuki/Library/Logs/Homebrew/z3... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/tree... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/wget... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/libidn2... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/ccache... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/python@2... (3 files, 123.9KB)
Removing: /Users/yuki/Library/Logs/Homebrew/go... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/gdbm... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/cmake... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/boost... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/libunistring... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/icu4c... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/nkf... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/readline... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/sqlite... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/yarn... (100B)
Removing: /Users/yuki/Library/Logs/Homebrew/solidity... (6 files, 563.5KB)
Removing: /Users/yuki/Library/Logs/Homebrew/nodebrew... (104B)
Removing: /Users/yuki/Library/Logs/Homebrew/gettext... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/watch... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/node... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/jenv... (100B)
Removing: /Users/yuki/Library/Logs/Homebrew/nmap... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/openssl... (64B)
Removing: /Users/yuki/Library/Logs/Homebrew/ethereum... (64B)
Pruned 0 symbolic links and 2 directories from /usr/local


サンプル的に試してみる

例えば、以下の郵便番号による住所検索 API

curl で実行して、それを jq コマンドにパイプで渡してみます(queryパラメータの postal に指定している値が郵便番号)

curl "http://geoapi.heartrails.com/api/json?method=searchByPostal&postal=1060032" | jq


実行してみると以下のようになります。

$ curl "http://geoapi.heartrails.com/api/json?method=searchByPostal&postal=1060032" | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1882    0  1882    0     0  59882      0 --:--:-- --:--:-- --:--:-- 60709
{
  "response": {
    "location": [
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木一丁目",
        "town_kana": "ろっぽんぎ1ちょうめ",
        "x": "139.740991",
        "y": "35.665082",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木二丁目",
        "town_kana": "ろっぽんぎ2ちょうめ",
        "x": "139.737087",
        "y": "35.666974",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木三丁目",
        "town_kana": "ろっぽんぎ3ちょうめ",
        "x": "139.735452",
        "y": "35.663977",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木四丁目",
        "town_kana": "ろっぽんぎ4ちょうめ",
        "x": "139.733837",
        "y": "35.665489",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木五丁目",
        "town_kana": "ろっぽんぎ5ちょうめ",
        "x": "139.735248",
        "y": "35.658358",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木六丁目",
        "town_kana": "ろっぽんぎ6ちょうめ",
        "x": "139.729932",
        "y": "35.659856",
        "prefecture": "東京都",
        "postal": "1060032"
      },
      {
        "city": "港区",
        "city_kana": "みなとく",
        "town": "六本木七丁目",
        "town_kana": "ろっぽんぎ7ちょうめ",
        "x": "139.726863",
        "y": "35.664751",
        "prefecture": "東京都",
        "postal": "1060032"
      }
    ]
  }
}

これだけで、JSONを見やすく整形した状態で出力してくれます


jq コマンドは、かなり色々とできるはずなので、使い方調べながらもっと使いこなせるようになりたいです。

codility - Arrays OddOccurrencesInArray

codility の OddOccurrencesInArrayを解いてみます。

問題の概要

  • インプット(引数)
    • 整数の配列
      • 配列の要素の整数は奇数
      • 配列の要素数は奇数個
      • 要素の値同士のペアができるが、1要素だけペアができない値が含まれている
      • 例:[9, 3, 9, 3, 9, 7, 9]
  • アウトプット(戻り値)
    • ペアができなかった要素の値
    • 例にあげた引数の場合、7 がアウトプットになります


解答

以下の方針でやってます。

  • まず配列をソートする。
  • ソートされているので、基本的に偶数番目と奇数番目の要素の値は一致する(ペアになる)はず。
  • ペアにならなかったら、その偶数番目の値が1個だけしか存在しないものということになるので、それがそのまま答え
  • 最後の最後まで進んだら最終要素が答えとなる
import java.util.Arrays;

class Solution {

    public int solution(int[] array) {
        Arrays.sort(array);

        for (int i = 0; i < array.length - 1;){
            if (array[i] != array[i + 1]) {
                return array[i];
            }
            i = i + 2;
        }
        return array[array.length - 1];
    }
}


これでやってみると結果は以下の通りで、問題ないようです。

f:id:nini_y:20190830204710p:plain