ふんばりフロントエンジニアのブログ

新米フロントエンジニアの備忘録です。ふんばり温泉タオル欲しい...

JavaScriptでオブジェクトから値を検索し、ソートする方法

最近まで会員サイトの構築に追われておりましたが、無事リリースすることができひと段落できました。

さて、今回はタイトルの通りJavaScriptのオブジェクト(連想配列)の値を検索してソートする方法についてご紹介していきたいと思います。

基本的なところだとは思うのですが、意外とJavaScriptのオブジェクトの扱いって難しかったりするんです。

ということで今回は下記のようなオブジェクトを検索&ソートしていきたいと思います。

const target = [
  {
    id: 1,
    name: '田中一郎',
    nameKana: 'タナカイチロウ',
    point: 0,
  },
  {
    id: 2,
    name: '田中二郎',
    nameKana: 'タナカジロウ',
    point: '',
  },
  {
    id: 3,
    name: '田中三郎',
    nameKana: 'タナカサブロウ',
    point: 3,
  },
  {
    id: 4,
    name: '田中四郎',
    nameKana: 'タナカシロウ',
    point: 5,
  },
  {
    id: 5,
    name: '田中五郎',
    nameKana: 'タナカゴロウ',
    point: 6,
  },
  {
    id: 6,
    name: '佐藤一郎',
    nameKana: 'サトウイチロウ',
    point: '',
  }
];


今回実装してみるのは下記の検索&ソートです。

  • 名前の部分一致検索
  • idの昇順/降順
  • pointが空のユーザーの検索

後述しますが、pointの昇順降順もidと同じように実装することができます。


では、実際のコードを見てみましょう。

/** search text **/
const searchTxt = (el,txt) => {
  return el.reduce((acc, val) => {
    if(val.name.indexOf(txt) !== -1 || val.nameKana.indexOf(txt) !== -1) {
      acc.push(val);
    }
    return acc;
  }, [])
}


const searchNoPoint = (el) => {
  return el.reduce((acc, val) => {
    if(val.point === '') {
      acc.push(val);
    }
    return acc;
  }, [])
}

/** sort **/
// aに二番目の値、bに一番目の値が入る
const sortUp = (a, b) => {
  return a.id - b.id;
}

const sortDown = (a, b) => {
  return b.id - a.id;
}


そして実際に動かしてみているのが下記になります。


やはりarray.reduceは便利ですね。

Array.prototype.reduce() - JavaScript | MDN

配列にしちゃえばなんでもreduceでなんとかなるのではないでしょうか?

また、sort関数ですが独自にソート用の関数を定義することができるため自由にソート条件をカスタマイズすることができます。(今回はただの昇順降順ですが...)

結局のところオペランドの真偽値で順番が決まるので、文字の昇順降順とかもいけるみたいです。

Array.prototype.sort() - JavaScript | MDN


そんなに濃い内容ではなかったですが、意外と使う機会が多い内容だったのではないでしょうか?

では今回はこのへんで...

Nuxt.jsのビルドについてまとめてみた デプロイに際して最適な方法は?

最近仕事でオーディションサイトを「Serverless+Nuxt.js」で作っているのですが、今回は初めてイケてると話題のNuxt.jsを業務で取り入れてみました。

 

右も左も分からなかったのですが、学習&実務で学習したことをお話ししていこうと思います。

 

今回お話しするのはNuxt.jsの「ビルド」についてです。

Nust.jsの「ビルド」とは

Nuxt.jsのビルドに関しては二つ種類があり、大別すると「SSR」か「そうでないか」だと思います。

SSRとは

SSRとは、サーバーサイドレンダリングの頭文字をとった単語ですがこちらはちゃんとSSRするには意外とめんどくさかったりします。

というのも、サーバーサイドレンダリングを行うにはNuxt.jsの中で下記のコマンドを実行しないとならないため。

```
nuxt build
nuxt start
```
こちらを実行しなければならないため、通常の静的なホスティング(S3など)ではNuxt.jsにおいてSSRを実現できないわけです。

というのも、nuxt startを実行するとポートが立ち上がりそれを解決しないと外部からのアクセスができないからですね。

しかし、後述するSPAモードやStaticモード(nuxt generateした場合)とは違い、Nuxt.jsのメリットであるSEOに適したビルドや非同期を用いたミドルウェアも実現できるので可能であればSSRでデプロイまでいけるのが一番最適な方法だと思います。

では、「そうでない方」はなんなのか

そうでない方(静的なビルド)とは

そうでない方は、SSRしないビルドです。

詳しく言えばNuxt.jsのSPAモードがそれにあたるでしょう。
また、modeはuniversalですが「nuxt generate」で静的なファイルを書き出している場合もこちらにあたります。

こちらの場合は、静的なホスティングになるのでデプロイ自体は簡単です。

SPAモードの場合は「nuxt.config.js」の「mode」を「spa」にして「nuxt build」をすると「dist」配下にソースが書き出されます。
また、「nuxt generate」の場合はも同じように 「dist」配下にソースが書き出されます。

この「dist」配下に書き出されたものをアップロードすればいいのでSSRモードのようにサーバー上でコマンドを実行しなければならない、ということはないわけです。

普通のhtmlをアップロードするような感覚でいけるわけですね。

では、Nuxt.jsにおいてSPAモードと「nuxt generate」で書き出した場合で何が違うのでしょうか?

Nuxt.jsのSPAモードと「nuxt generate」の違いについて

これらの違いですが、SPAモードでは

一方「nuxt generate」で書き出した静的なファイルの場合には

  • vue-metaが使える
  • レスポンスが早い

というそれぞれのメリットがあると思います。

ただ、ほとんどの場合でSPAモードのメリットを享受したい場合はSSRモードでデプロイすると思います....

しかし、完全に静的なファイルで書き出すとなるとミドルウェアAPIを叩いてどうこうする、といったことができなくなるのでmetaタグが全ページで同じであればいい、ということあればSPAモードは非常に有用です。(実際に今回の案件ではSPAモードで実装しようと考えているので...)

かなり案件の要件によってビルドの方法は変わってくると思いますが、出来るだけSSRモードでビルドした方がNuxt.jsの恩恵を受けられるでしょう。

しかし、s3などの静的ホスティングの場合、つまりレスポンスが重要でそこまで動的にルーティングや情報が変わらない場合はSPAモードか「nuxt generate」で書き出した方がいい場合もあります。

Nuxt.jsは個人的にかなり気に入ったので次回はこれらを踏まえて早めの段階からデプロイを見据えて検討しようと思います。

JavaScriptでオブジェクトのvalueでソートする方法

めっちゃ久々になりました...

お仕事落ち着いてきたので再開しようと思います笑

今回は「単純に見えてやってみると意外と難しい!」と友人から質問を受けたオブジェクトのソートです。

今回のソート条件としては単純で、下記のようなオブジェクトのvalueでソートをかけたいとのこと。

let obj = {
  kinmu_0: 500, 
  zangyo_0: 400, 
  zangyo_1: 300,
  shinyaZangyo_0: 200,
  endTIme: 100
}

「そんな難しいか...?」と思ったのですが、PHPとかJavaとかと違ってJavaScriptの配列、もといオブジェクトって意外と曖昧かつ複雑だったりするんですよね〜

てな訳でやってみたのがこちらです。

let obj = {
  kinmu_0: 500, 
  zangyo_0: 400, 
  zangyo_1: 300,
  shinyaZangyo_0: 200,
  endTIme: 100
}

let array = [];

for (let [key, value] of Object.entries(obj)) {
  array.push({[key]: value});  // 躓きポイント
}

function compare(a, b) {
  const numA = Object.values(a);
  const numB = Object.values(b);
  
  let comparison = 0;
  if (numA > numB) {
    comparison = 1;
  } else if (numA < numB) {
    comparison = -1;
  }
  return comparison;
}


array.sort(compare);

流れとしては一旦配列に変換してsort関数を適用する、といった流れになっています。

おそらく友人が今回の質問で躓いていたのはおそらくオブジェクト→配列への変換だったのではないかなーと思ってます。

躓きポイントとしてコメントアウトしている部分、実は最初私はこのように書いていたんです。

  array.push({key: value}); 

これだと、変数名を解決してくれずただkeyというキーが設定されてしまいます。 ただ、変数を「[]」で囲んであげれば変数を解決してくれます。

これで配列への変換は完了しましたね。

あとはソートなのですが、配列にしてしまえばあとは簡単です。

普通の配列のソートと変わらずソートの関数を作ってコールバックでオブジェクトのvalueを比較してあげれば終了です。

なんだかんだ30分くらいかかってしまったのでもっとオブジェクトに対する理解を深めなければなーと感じました

LaravelでFactoryとSeederを使ってダミーデータを追加する簡単な例

タイトルの通りです。

備忘録的に簡単なFactoryとSeederを使用したダミーデータの追加例を残しておきます。

FactoryとSeederとは

Factoryは追加するダミーデータの型みたいなものを定義するところです。
その名の通り、人形焼の鋳型を生産する工場的なものだと思っておきましょう。

Seederは実際にデータベースにダミーデータを追加するところです。
Factoryを使わなくてもSeederだけでダミーデータを追加することもできるみたいですね。

FactoryとSeederを使ったダミーデータ追加の簡単な例

全体的な流れ
  1. Factoryでデータモデルの定義

Seederで実際にデータの追加処理を定義
Seederを実行

手順

1. SeederとFactoryのファイルを作る。

php artisan make:seeder OrdersTableSeeder
php artisan make:factory OrdersFatctory --model=Orders 

Factoryを作る際は上記のようにmodelを指定することをおすすめします。

2. Factoryでデータのモデルを作る。

$factory->define(Orders::class, function (Faker $faker) {
    $drink = ['ビール','ハイボール','チューハイ'];

    return [
        'user_id' => $faker->numberBetween(3, 4),
        'drink' => $faker->randomElement($drink)
    ];
});

defineの第一引数がしっかり先頭が大文字になるモデル名の指定になっているか確認。
ちゃんとした指定になっていないと「Unable to locate factory with name [default]」のエラーが出る。
$fakerはダミーデータ作成をするために使うライブラリ。別に使わないでベタ書きでもいい。
$fakerで使えるデータ一覧↓
qiita.com


3. Seederでデータの作成

 public function run()
    {
        factory(App\Orders::class, 50)->create();
    }

factoryメソッドの第一引数にモデルクラス、第二引数にデータの数を入れるだけ。

4. DatabaseSeeder.phpにSeederの登録

public function run()
    {
         $this->call(OrdersTableSeeder::class);
    }

artisanのdb::seedコマンドで実行されるのがこのファイルのよう。
「--class=[seeder名]」で実行seederを指定できた時代もあったが現在はできなさそう。

5. Seederを実行

php artisan db::seed


簡単な例ではありましたが、なんとなく流れがわかってもらえたら嬉しいです。

【CodeIgniter】dockerで構築したらform_openのurlがおかしくなった件

dockerでcodeigniterの環境を作っていて、公式チュートリアルをやっていたところform_openというメソッドを使うとURLがおかしくなってしまう、という現象に出くわしました。

form_openというのは、formを生成してくれるCodeIgniter独自の関数です。

どのようにおかしくなったかというと、formのactionのURLが想定していたURLと違ったんですね。

というのも、私が立ち上げていたapacheのIPは「localhost:1111」。

つまり、actionのURLも「localhost:1111〜」となるのが望ましいです。

しかし、action属性を見てみると次のようなURLになっていました。

f:id:ma1129nm:20190419163021p:plain

このform_openという関数はconfig.phpのbase_urlを基準にURLを決定するらしく、確かにconfig.phpを見てみると何も記載してありませんでした。

$config['base_url'] = '';

そのため、下記のようにbase_urlを指定してあげたところ問題なくURLが指定したURLに置き換わりました。

$config['base_url'] = 'http://localhost:1111';


さて、「192.168.128.3ってなんぞ?」と思っていたのですがなんだか見覚えが…

とりあえず、apacheのコンテナに入って「hostname -i」でIPを調べたらまさにこの番号でした。

つまり、何も指定しないとdockerのコンテナのIPがbase_urlになってしまうということなんですね。

初めてCodeigniter触りましたが、今のところLaravelやCakePHPよりも自由度が高そうな感触。

とりあえず何か作ってみようかな…

TweenMaxとScrollMagicを関数化してみたお話

連投です(笑)

今回はいたってシンプルなお話で、TweenMaxとScrollMagicを関数化したというお話です。


See the Pen
scrollMagicTweenFunction
by nakajima masahiro (@nakajima333ta)
on CodePen.

なんとなく、TweenMaxとScrollMagicを使っている中で一々同じコード書くのめんどくさいなあ、と思ったことがきっかけで関数化に至りました。

あまりやっている方がいなかったので出来ないのか思っていたのですが関数化だけなら問題ありませんでしたね。

【ScrollMagic】onメソッドとは?簡単な例を紹介します

しばらく暇らしいので連投します(笑)

前回に引き続き、webページのアニメーションをさせる際によく使うライブラリであるScrollMagicについてお話していこうと思います。

ScrollMagicはその名の通り、スクロールをして指定した要素に到達した際にイベントやらアニメーションを発火させるやらができるライブラリです。


簡単な例は以下の通り。


See the Pen
scrollMagicPinSample
by nakajima masahiro (@nakajima333ta)
on CodePen.

こちらは、指定した要素に到達したらその要素を指定した時間(duration)分ピン留するという処理となっています。

このように、ScrollMagicの組み込みのメソッドで色々できる場合もありますし、組み込みのメソッドではないとできない処理などもあります。

例えば、上記の例のようなピン留やGSAPと連携したsetTweenメソッドなどがその例でしょう。

ただ、単にクラスを追加したい場合などもあるわけですよね。

そんな時によく使うのが「on」メソッドです!

onメソッドは、簡単に言ってしまえばコールバックを使うことができるメソッドです。

まず、例を見てみましょう。


See the Pen
scrollMagicPinSample
by nakajima masahiro (@nakajima333ta)
on CodePen.

こちらは、「trigger」クラスに到達したら「changeColor」クラスを付与して、離れたらクラスを取り除くという処理になっています。

このように、onメソッドのイベントリスナとしてenterやleaveを利用することができ、そのコールバックとして第二引数の関数を実行することができるわけです。

tweenアニメーションのセットなどはsetTweenメソッドで組み込むしかありませんが、簡単なクラスの付与はonメソッドを使った方がいいでしょう。


ちなみに、使えるイベントハンドラはこんな感じ。

  • change
  • update
  • progress
  • start
  • end
  • enter
  • leave

それぞれの使い所は様々ですが、個人的にはenter、leave、center、progressくらいがよく使うイメージです。

今回の案件では、全てTweenアニメーションで実装したわけではなく一部CSSアニメーションを使った部分もあり、アニメーションをクラスで管理していたのでonメソッドはかなり重宝しました!

ScrollMagicは一見ややこしい部分もありますがなれたらかなり便利なライブラリなので、これからも積極的に使っていきたいですね。