2021/06/16

Compare two arrays is equal in JavaScript

ๅœจ PHP ไธญ,ๅฏไปฅ็ฐกๅ–ฎไฝฟ็”จๆฏ”่ผƒ้‹็ฎ—ๅญๆฏ”ๅฐๅ…ฉๅ€‹้™ฃๅˆ—。

$a = ['a', 'b', 'c'];
$b = ['a', 'b', 'c'];

var_dump($a === $b); // true

็”š่‡ณๆŽ’ๅบไธไธ€ๆจฃ้€้Ž sort ไนŸๅฏไปฅ่งฃๆฑบ。

$a = ['a', 'b', 'c'];
$b = ['a', 'c', 'b'];

var_dump(sort($a) === sort($b)); // true

ไฝ†ๅœจ js ็š„ไธ–็•Œไธ่กŒ。

const a = [
    'a',
    'b',
    'c'
];
const b = [
    'a',
    'b',
    'c'
];

console.log(a == b); // false
console.log(a === b); // false

ๅœจ็ถฒ่ทฏไธŠ็œ‹ๅˆฐไธ€ๅ€‹่งฃๆณ•ๆŒบๅฅฝ็š„,่จ˜้Œ„ไธ€ไธ‹。

const a = [
    'a',
    'b',
    'c'
];
const b = [
    'a',
    'b',
    'c'
];
const result = a.sort().every((value, index) => {
    return value === b.sort()[index];
});

console.log(result); // true

ๅฏซๆˆ prototype ๅฐฑๆ˜ฏ。

const a = [
    'a',
    'b',
    'c'
];
const b = [
    'a',
    'b',
    'c'
];

Array.prototype.equals = function (array) {
    return this.sort().every((value, index) => {
        return value === array.sort()[index];
    });
}

console.log(a.equals(b)); // true

2021/05/07

ไฝฟ็”จ CSS ่ฎ“ๅœ–็‰‡ไธ็ ดๆ ผ

็พๅœจๆ˜ฏ responsive ็š„ๆ™‚ไปฃ,ๆ‰€ๆœ‰็š„้ ้ข้ƒฝๅฟ…้ ˆๅš้Ÿฟๆ‡‰ๅผ,่™•็†้€™็จฎ็ถฒ็ซ™็š„ๆ™‚ๅ€™,ๅœ–็‰‡ๆœ€ไปคไบบ้ ญ็—›,ๆœ‰ๆ™‚ๅ€™็„กๆณ•่ฆ็ฏ„ๅฎขๆˆถๆ˜ฏๅฆๅ‚ณๆˆ‘ๅ€‘่ฆๆฑ‚็š„ๆฏ”ไพ‹,ๆ‰€ไปฅๅฟ…้ ˆๅœจๅ‰็ซฏๅšไธ€ไบ›ๆ‰‹่…ณ่ฎ“็•ซ้ข็œ‹่ตทไพ†่ตท็ขผไธ้‚ฃ้บผ็ณŸ。

html
<div class="container">
    <div class="row row-no-gutters">
        <div class="col-md-3">
            <div class="box">
                <img src="https://via.placeholder.com/700x400.png">
            </div>
        </div>
        <div class="col-md-3">
            <div class="box">
                <img src="https://via.placeholder.com/600x400.png">
            </div>
        </div>
        <div class="col-md-3">
            <div class="box">
                <img src="https://via.placeholder.com/600x200.png">
            </div>
        </div>
        <div class="col-md-3">
            <div class="box">
                <img src="https://via.placeholder.com/300x500.png">
            </div>
        </div>
    </div>
</div>

้€™ๆ˜ฏๅคง้ƒจๅˆ†ไฝฟ็”จ bootstrap ๆ™‚ๆœƒไฝฟ็”จ็š„ๆŽ’็‰ˆ,ไธ€ๅ€‹ๅ››ๆ ผๅœ–็‰‡็š„้…็ฝฎ,ๆˆ‘ๆ”พไบ†ๅนพๅผตๅฎŒๅ…จไธๅŒๅฐบๅฏธ็š„ placeholder ๅœ–็‰‡,ไธ€่ˆฌไบบ่™•็†ๆœƒๅœจ img ไธŠไธ‹ max-width: 100%,่ฎ“ไป–ๅฏฌๅบฆไธๆœƒ็ˆ†่กจ,ไฝ†้ซ˜ๅบฆ็š„้ƒจๅˆ†ๅฐฑๆœƒ่ขซๅœ–็‰‡ๆ’้ซ˜ไบ†,ๆœ‰ไบ›ไบบๆœƒๆŠŠๅœ–็‰‡่ฎŠๆˆ background,ๅ†ๅˆฉ็”จ cover ๅฑฌๆ€งๆญ้… padding-top + overflow: hidden ๆ’้ซ˜ๅบฆ่ฎ“ๅœ–็‰‡็ฝฎไธญไธฆไธ”ไธ็ ดๆ ผ,ไฝ†้€™ๆจฃๆœƒๅฝฑ้Ÿฟ SEO,ๆˆ‘่‡ชๅทฑ่ฉฆๅ‡บไบ†ไธ€ๅ€‹้…็ฝฎ้‚„ไธ้Œฏ。

scss
.container {
  .box {
    width: 100%;
    padding-top: 66.6%;
    overflow: hidden;
    position: relative;
    border: 1px solid grey;
  }

  .box {
    img {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }
}

้€™ๆจฃ็š„้…็ฝฎๆณ•ๅฏไปฅๅœจไธๅฐ‡ๅœ–็‰‡่ฎŠๆˆ background ็š„ๆƒ…ๆณไธ‹่ฎ“ๅœ–็‰‡ๆปฟ็‰ˆๅฑ…ไธญ,IE 11 ไปฅไธ‹ไธๆ”ฏๆด,ไธ้Žๆˆ‘ไธๅœจไนŽ。

2021/05/05

Vagrant provision with docker and docker-compose install

vagrant ๆไพ›ไบ† provision ๅˆๅง‹ๅŒ–ๅŠŸ่ƒฝ,ๅฏไปฅ้กžไผผ Dockerfile ๅœจๅˆๅง‹ๅŒ– vagrant ็š„ๆ™‚ๅ€™ๅฐฑๆŠŠๆƒณ่ฆๅฎ‰่ฃ็š„ๅ…งๅฎน่™•็†ๅฅฝ,ไธ‹้ข็คบ็ฏ„ไธ€ไธ‹ๅฆ‚ไฝ•ๅฎ‰่ฃไธ€ๅ€‹ไนพๆทจ็š„ ubuntu ๅพŒๆŠŠ docker ไปฅๅŠ docker-compose ไธ€ไฝตๅฎ‰่ฃ。

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/focal64"

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
  end

  config.vm.provision "shell", inline: <<-SHELL
    docker -v &> /dev/null

    if [[ $? != 0 ]]; then
      echo "start install docker"
      curl -sL https://get.docker.com/ | sudo bash
      sudo usermod -aG docker vagrant
      docker -v
    else
      echo "docker installed"
    fi

    docker-compose -v &> /dev/null

    if [[ $? != 0 ]]; then
      echo "start install docker-compose"
      sudo curl -sL "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
      sudo chmod +x /usr/local/bin/docker-compose
      sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
      docker-compose -v
    else
      echo "docker-compose installed"
    fi
  SHELL
end

็”ฑๆ–ผ provision ๆœ‰ๅฏ่ƒฝ้‡่ค‡ไฝฟ็”จ,ๆ‰€ไปฅๆœ€ไธ€ไบ›ๅŸท่กŒๆชขๆŸฅๆ˜ฏๅฟ…่ฆ็š„,้€™้‚Šๆˆ‘ๆชขๆŸฅๅทฒๅฎ‰่ฃ็š„ๆŠ€ๅทงๆ˜ฏไฝฟ็”จ -v ้€™ๅ€‹ๅƒๆ•ธ,ๅฆ‚ๆžœๆฒ’ๆœ‰ๅฎ‰่ฃ,็ณป็ตฑๆœƒๅ ฑ้Œฏ,ๅ› ๆญค $? ๆœƒ้ž 0,่—‰ๆญคๅˆคๆ–ทๆœ‰ๆฒ’ๆœ‰ๅฎ‰่ฃ้Ž。

2021/04/09

FormArray And Checkbox

ๆœ€่ฟ‘ๅœจๅญธ Angular,ไป–็š„ Form ็›ธ้—œๆจก็ต„ๆŒบๆœ‰่ถฃ็š„,ไธ้Ž็‚บไบ†ๅฏฆ็พๆŸไบ›ๅŠŸ่ƒฝ้‚„ๆ˜ฏๅฟ…้ ˆ้€้Ž JS ๅŠ ๅทฅ,้€™้‚Š่จ˜้Œ„ไธ€ไธ‹ๆ€Ž้บผ็ถ checkbox ็š„ cheked ็ตๆžœๅˆฐ FormBuilder ไธŠ。

html
<h3>{{ form.value | json }}</h3>  
<div [formGroup]="form">  
 <input type="text" formControlName="name">  
 <ng-container *ngFor="let hobby of hobbies">  
 <label> <input type="checkbox" [value]="hobby.value" (click)="updateHobbies($event)">  
  {{ hobby.name }}  
  </label>  
 </ng-container></div>
ts
import { Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormControl } from '@angular/forms';

@Component({
  selector: 'app-checkbox',
  templateUrl: './checkbox.component.html',
  styleUrls: ['./checkbox.component.scss']
})
export class CheckboxComponent implements OnInit {
  public form = this.fb.group({
    name: [''],
    hobbies: this.fb.array([])
  });
  public hobbies: object[] = [
    { name: 'basketball', value: 'basketball' },
    { name: 'baseball', value: 'baseball' },
    { name: 'tennis', value: 'tennis' },
  ];

  constructor(
    private fb: FormBuilder
  ) { }

  ngOnInit(): void {
  }

  public updateHobbies(e): void {
    const hobbies: FormArray = this.form.get('hobbies') as FormArray;

    if (e.target.checked) {
      hobbies.push(this.fb.control(e.target.value));
    } else {
      let i = 0;

      hobbies.controls.forEach((control: FormControl) => {
        if (control.value === e.target.value) {
          hobbies.removeAt(i);

          return;
        }

        ++i;
      });
    }
  }
}

2021/02/01

Work With Typescript And Webpack And Route

ๅ‘ˆไธŠๅ€‹ๆ–‡็ซ ,ๅฆ‚ๆžœๆˆ‘ๅ€‘ๆƒณๆœ‰้กžไผผ SPA ้‚ฃ็จฎ routes ็š„ๅŠŸ่ƒฝ,่ฎ“้‡่ค‡่ณ‡ๆบๅฆ‚ jQuery ็ตฑไธ€ไธ€ๅŒ…่ฉฒๆ€Ž้บผๅฏฆๅš。

็›ฎ้Œ„็ตๆง‹

|   a.html
|   b.html
|   tsconfig.json
|   webpack.config.js
+---app
|
\---src
    |   main.ts
    |   routes.ts
    \---class
            a.ts
            b.ts
            main.interface.ts

ๆˆ‘ๆŠŠ index.ts ๆ”นๆˆไบ† main.ts,ๅขžๅŠ ไบ†,็จ‹ๅผ็ขผๅ…งๅฎนๅฆ‚ไธ‹:

a.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Typescript + Webpack</title>
    <script src="app/main.js"></script>
</head>
<body id="a">
    <div id="content"></div>
</body>
</html>
b.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Typescript + Webpack</title>
    <script src="app/main.js"></script>
</head>
<body id="b">
    <div id="content"></div>
</body>
</html>
main.ts
import $ from 'jquery';
import { routes } from './routes';

$(function () {
    const classLoader = async (routeName: string): Promise<any> => {
        const imported = await import('./class/' + routeName);
        const className = routeName.toUpperCase();

        return new imported[className]();
    }

    routes.forEach(route => {
        if ($(`body#${route}`).is('*')) {
            classLoader(route).then(target => target.init());

            return false;
        }
    });
});
routes.ts
export const routes: string[] = [
    'a',
    'b'
]
webpack.config.js
const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: {import: './src/main.ts'}
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/,
            },
        ],
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
    },
    output: {
        path: path.resolve(__dirname, 'app'),
    },
};
main.interface.ts
export interface mainInterface {
    init(): void
}
a.ts
import { mainInterface } from './main.interface';
import $ from 'jquery';

export class A implements mainInterface {
    init(): void {
        $('div#content').html('a');
    }
}
b.ts
import { mainInterface } from './main.interface';
import $ from 'jquery';

export class B implements mainInterface {
    init(): void {
        $('div#content').html('b');
    }
}

N.html ๅฐๆ‡‰ N.ts,ๅฐ‡ๆ‰€ๆœ‰่ฆๅฐๆ‡‰็š„ class ่จญๅฎšๅŠ ๅˆฐ routes.ts,main.ts ๆœƒๅ‹•ๆ…‹ๅตๆธฌๅˆฐ html ๆช”ๆกˆ็š„ body ๆœ‰ๆฒ’ๆœ‰็›ธๅฐๆ‡‰็š„ id,ๆœ‰็š„่ฉฑๅฐฑๅŽปๆ’ˆ็›ธๅฐๆ‡‰็š„ class,่€Œ็›ธๅฐๆ‡‰็š„ class ็นผๆ‰ฟ interface ไธ€ๅฎš่ฆๆœ‰ init() ้€™ๅ€‹ method,ๆœ€็‚บ้€™ๅ€‹้ ้ขๆ™‚่ฆๅš็š„้ ่จญไบ‹ไปถ,้€™ๆจฃ compile ็š„็ตๆžœ jQuery ๆˆ–ๅ…ถไป–็š„ๅฅ—ไปถๅชๆœƒๆœ‰ไธ€ไปฝ,ไธฆไธ”ๅšๅˆฐ้š”้›ขไธๅŒ้ ้ขๆ‰€้œ€่ฆ็š„ๅŠŸ่ƒฝ。

2021/01/29

Work With Typescript And Webpack

ๅ› ็‚บๅทฅไฝœ็š„้—œไฟ‚ๆŽฅ่งธไบ† angular,ๆ‰€ไปฅๅญธ็ฟ’ไบ† typescript,่ฆบๅพ—้€™ๅทฅๅ…ทๅพˆๅฅฝ็”จ,ๆ–ผๆ˜ฏๅธŒๆœ›ๅœจ้ž angular ็š„็’ฐๅขƒไธ‹ๅฏซ js ๆ™‚ไนŸ็”จ typescript,้€™ๆ™‚่ฆๅ€Ÿ็”จ webpack ๅนซๅฟ™ๆ‰“ๅŒ…ๆˆ browser ๅฏไปฅไฝฟ็”จ็š„ๅ…งๅฎน。

็›ฎ้Œ„็ตๆง‹

├─app
└─src
    │  index.ts
    │
    └─class
            chan.ts
│  index.html
│  tsconfig.json
│  webpack.config.js

config

tsconfig.json
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "allowJs": true
  }
}

typescript ็š„ๅŸบ็คŽ้…็ฝฎ

webpack.config.js
const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        index: {import: './src/index.ts'}
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/,
            },
        ],
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
    },
    output: {
        path: path.resolve(__dirname, 'app'),
    },
};

webpack ็š„้…็ฝฎ,ๆœƒๆŽƒๆ entry ๆˆ‘ๆŒ‡ๅฎš็š„ๆช”ๆกˆ่ผธๅ‡บๅˆฐ app ๅŒๆจฃ็š„ๆช”ๅ,็”จ้ž spa ็š„ๆ–นๅผ้–‹็™ผๅพ€ๅพ€้‚„ๆ˜ฏไธๅŒ้ ้ขไฝฟ็”จไธๅŒ็š„ js,ๆ‰€ไปฅ้€™ๅ€‹ๆžถๆง‹ๅฐ user ไธฆไธ่ƒฝ็ฏ€็œ่ณ‡ๆบ,ๅ› ็‚บๆฏๅ€‹ js ้ƒฝๆœƒๅŒ…ไธ€ไปฝ jquery,ๅชๆ˜ฏๅฐ้–‹็™ผ่€…ๆ–นไพฟ็š„ๅทฅๅ…ท่€Œๅทฒ,้™ค้žไฝ ๆœ‰ๆŠŠๆกๆŠŠ็จ‹ๅผๅฏซๅˆฐๆฏๅ€‹้ ้ข้š”้›ขไธไบ’็›ธๅนฒๆ“พ,้‚ฃๅฐฑๅฏไปฅไธ€ๆ”ฏๆช”ๆกˆๆ‰“ๅคฉไธ‹,ไนŸๆ˜ฏ spa ็š„้‹ไฝœๆ–นๅผ。

npm i --save webpack webpack-cli typescript ts-loader

ๅฎ‰่ฃ compiler ้œ€่ฆ็š„ๅทฅๅ…ท

ไฝฟ็”จๆ–นๅผ

npm i -s jquery dayjs
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Typescript + Webpack</title>
    <script src="app/index.js"></script>
</head>
<body>
    <div id="content"></div>
</body>
</html>
index.ts
import $ from 'jquery';
import { Chan } from './class/chan';

$(function () {
    const chan = new Chan();

    $('div#content').html(chan.getNow());
});
chan.ts
import dayjs from 'dayjs';

export class Chan {
    public getNow(): string {
        return dayjs().toString();
    }
}

ไฝฟ็”จ webpack compiler ไน‹ๅพŒๆˆ‘ๅ€‘้ ้ขไธŠ็š„ div#content ๆœƒๅ‡บ็พ Fri, 29 Jan 2021 09:09:52 GMT,ๅคงๅŠŸๅ‘Šๆˆ。

2020/12/22

Delete None Keeping Files

็•ถๆˆ‘ๅ€‘ๅœจๅ‚™ไปฝๆ–‡ไปถ็š„ๆ™‚ๅ€™,้€šๅธธๅชไฟ็•™ไธ€ๅฎš็š„ๆ•ธ้‡,ไพ‹ๅฆ‚่ชช 10 ๅคฉไปฝ,ๆˆ‘ๅ€‘ๅฏ่ƒฝๆœƒ้€™ๆจฃๅฏซ:

$ find PATH_TO_FILES -mtime +30 | xargs rm -f &> /dev/null
$ find PATH_TO_FILES -mtime +30 -exec rm {} \ &> /dev/null;

้€™ๅ…ฉ็จฎๅฏซๆณ•็ตๆžœไธ€ๆจฃ,้ƒฝๆ˜ฏๆœƒๅˆช้™คๅปบ็ซ‹่ถ…้Žไธ‰ๅๅคฉไปฅไธŠ็š„ๆช”ๆกˆ,ไธ้Ž้€™ๆœƒๆœ‰ๅ€‹ๅ•้กŒ,ๅ‡่จญไปŠๅคฉๅ› ็‚บๆŸไบ›ๅ› ็ด ๅ‚™ไปฝๆŒ‡ไปคไธญๆ–ทไบ†,ไฝ† crontab ไพ่ˆŠๅœจ่ท‘ๅˆช้™คๆŒ‡ไปค,่‹ฅ op ๆฒ’ๆœ‰ๅŠๆ™‚็™ผ็พ,ๅ‚™ไปฝๆช”็ต‚็ฉถๆœƒ่ขซๅˆชๅ…‰,ๅ› ๆญคๅฆไธ€็จฎๅฏซๆณ•ๆˆ‘่ช็‚บๆ˜ฏๆฏ”่ผƒๅฅฝ็š„

ๆˆ‘ๅ€‘ๅ…ˆ่ฃฝ้€ ๅ…ญๅ€‹ๆช”ๆกˆ

i=1; while [ $i -lt 7 ]; do touch $i; ((i++)); done

$ ll -d ./*
-rw-r--r-- 1 root root 0 12ๆœˆ 22 11:45 ./1
-rw-r--r-- 1 root root 0 12ๆœˆ 22 11:45 ./2
-rw-r--r-- 1 root root 0 12ๆœˆ 22 11:45 ./3
-rw-r--r-- 1 root root 0 12ๆœˆ 22 11:45 ./4
-rw-r--r-- 1 root root 0 12ๆœˆ 22 11:45 ./5
-rw-r--r-- 1 root root 0 12ๆœˆ 22 11:45 ./6

ๅ‡่จญๆˆ‘ๅ€‘ๅช่ฆไฟ็•™ 5 ๅ€‹ๆช”ๆกˆ,ๆŒ‡ไปคๅฐฑๆ˜ฏ:

$ ls -ltd ./* | tail -n +6 | awk '{print $NF}' | xargs rm -f &> /dev/null

-d ้Žๆฟพไบ† ./ ไปฅๅŠ ../,-t ๆœƒ็…งๆ™‚้–“ๆŽ’ๅบ,tail -n +6 ๅฐฑๆ˜ฏๆ‹‰ๅ‡บ่ถ…้Ž n ๆ•ธ้‡็š„็ตๆžœ,่ฆไฟ็•™ 5 ไปฝ็š„่ฉฑ่ฆๅกซๅ…ฅ 6,ๆ‰€ไปฅๆช”ๅ 1-6 ๆ™‚ 6 ๆœƒ่ขซ็ฏฉ้ธๅ‡บไพ†,awk '{print $NF}' ๆœƒๅฐๅ‡บ็ฏฉ้ธๅ‡บไพ†่ณ‡่จŠ็š„ๅฐพ็ซฏ,ไนŸๅฐฑๆ˜ฏๆช”ๅ,ๆœ€ๅพŒๅฐฑ็”จ xargs rm -f ๅˆช้™ค่ฉฒๆช”ๆกˆ,้€™ๆจฃๅฏซ็š„่ฉฑไธ็ฎกๆ™‚้–“็š„ๅฝฑ้Ÿฟ่ฉฒๅ‚™ไปฝ็›ฎ้Œ„ๆฐธ้ ๆœƒ็•™ไธ‹ไฝ ๆŒ‡ๅฎš็š„ๆช”ๆกˆๆ•ธ้‡。