動かざることバグの如し

近づきたいよ 君の理想に

Linuxでエクセルが読めるCSVに変換する方法

環境

やりたいこと

エクセルではシフトJIS(CP932)のCSVしか読めないので、UTF-8CSVは悲しいことに文字化けしてしまう。

文字コードを変換したい

コマンド

cat users.csv| nkf -s --cp932 --fb-subchar=0x3013 > users_cp932.csv
  1. cat users.csv: users.csvファイルの内容を標準出力に表示。
  2. |: パイプ。前のコマンドの出力を次のコマンドの入力にする。
  3. nkf -s --cp932 --fb-subchar=0x3013: nkfコマンドで文字コードShift_JISに変換。--cp932WindowsShift_JISを指定し、--fb-subchar=0x3013は変換できない文字を「〓」に置き換える。
  4. > users_cp932.csv: 変換後の内容をusers_cp932.csvファイルに保存。

ペルソナ像を作成するプロンプト

ペルソナ像を作成するプロンプト

あなたはマーケティングの専門家です。
ターゲットオーディエンスとして「ぴえん系女子」という特定のペルソナ像を作成してください。
「外見」「性格・内面的特徴」「行動パターン」「過去」の項目について、それぞれ5つの特徴を箇条書きで説明してください。

あなたはマーケティングの専門家です。
ターゲットオーディエンスとして「20歳、女子、歌舞伎町、ぴえん系女子」という特定のペルソナ像を作成してください。
「外見」「性格・内面的特徴」「行動パターン」「過去」の項目について、それぞれ5つの特徴を箇条書きで簡潔に説明してください。

TypeScriptで配列から指定数ランダム抽出するメソッド

やりたいこと

例えば以下のような配列があったとする。

const fruits = [
  "りんご",
  "バナナ",
  "オレンジ",
  "いちご",
  "ぶどう",
  "メロン",
  "パイナップル",
  "マンゴー",
  "スイカ",
  "さくらんぼ"
];

この中から重複せずにランダムに3つ取得したい。

コード

function getRandomElements<T>(arr: T[], count: number): T[] {
  if (count > arr.length) {
    throw new Error('Count is greater than the array length');
  }

  const result: T[] = [];
  const usedIndices: Set<number> = new Set();

  while (result.length < count) {
    const randomIndex = Math.floor(Math.random() * arr.length);
    if (!usedIndices.has(randomIndex)) {
      usedIndices.add(randomIndex);
      result.push(arr[randomIndex]);
    }
  }

  return result;
}

実行すると

getRandomElements(fruits, 3)
>  ['さくらんぼ', 'ぶどう', 'マンゴー']
getRandomElements(fruits, 2)
> ['りんご', 'パイナップル']

のようにできる。

コードの解説

  • getRandomElements<T>(arr: T[], count: number): T[] 関数の定義:
    • ジェネリック<T> を使って、任意の型の配列を受け取れるようにする。
  • 引数のチェック:
    • if (count > arr.length) で、要求した要素数が配列の長さを超えないことを確認。超えた場合はエラーをスロー。
  • 結果を格納するための配列 result と、使用したインデックスを管理するための Set 型の usedIndices を定義。
  • ランダムな要素を取得するループ:
    • while (result.length < count) で、必要な数のランダムな要素が取得できるまでループ。
    • 各ループ内で、Math.random() を使ってランダムなインデックスを生成。
    • そのインデックスが usedIndices に存在しない場合のみ、結果に追加する。
  • 最終的に、重複のないランダム要素が含まれた配列を返す。

注意点

  • 重複を避けるために、配列の長さより多くの要素を要求しないこと。
  • Set を使用しているため、インデックスの管理が効率的。
  • 配列の長さが少ない場合、要求する要素数を注意深く設定する必要がある(特に小さな配列の場合)。
  • 整数の除外やオフセットの設定はしていないため、配列の先頭から詳細な参照が必要な場合は注意が必要。

TypeScriptで複数行文字列のインデント問題を解決するts-dedent

環境

  • Nodejs v22

やりたいこと

複数行の文字列を変数として持っておきたいので、ここではテンプレートリテラルを使う。テンプレートリテラルは、JavaScript(およびTypeScript)の便利な機能で、複数行の文字列を簡潔に扱える。この機能の主なメリットは以下の通りだ。

  1. 可読性の向上: コードをそのまま書けるため、文字列の内容を確認しやすい。通常の文字列とは異なり、改行やインデントもそのまま表現できる。

  2. 変数埋め込みが簡単: ${}の形式を使うことで、文字列内に変数や式を埋め込むことができ、動的な文字列生成が容易になる。

  3. 長いメッセージやテンプレートの管理が改善: HTMLやMarkdownなどの長い文を管理する際に、テンプレートリテラルを使うと、コードがすっきりする。

例えば以下のTypeScriptコードがあったとする。

const hogehoge = () => {
  return `
  複数行でインデントが入ってる文章
  複数行でインデントが入ってる文章
  `;
};

console.log(hogehoge());

インデント揃えるとそれも反映されてしまう問題

上のサンプルコードでは、テンプレートリテラルを使って生成した文字列には、インデントがそのまま出力に反映されてしまう。この場合、意図しない空白が入ってしまうことがある。

❯ npx -y tsx ./src/scripts/dedent.ts

  複数行でインデントが入ってる文章
  複数行でインデントが入ってる文章

解決方法

TypeScriptなので、ts-dedentを使う

インストール

npm install ts-dedent

使い方

テンプレートリテラルのバッククオート前に「dedent」と書くだけ。さっきのサンプルコードに反映させてみる。

import dedent from 'ts-dedent';

const hogehoge = () => {
  return dedent`
  複数行でインデントが入ってる文章
  複数行でインデントが入ってる文章
  `;
};

console.log(hogehoge());

するとちゃんと不要な空白をトリムしてくれて本来出力したかったテキストになっている。

❯ npx -y tsx ./src/scripts/dedent.ts
複数行でインデントが入ってる文章
複数行でインデントが入ってる文章

注意点

ts-dedentを使用する際の注意点は、使用するテンプレートリテラルの内容によっては、期待通りに動作しない場合があることだ。特にインデントの管理においては、どの程度の空白を取り除くかを必ず確認する必要がある。意図しないトリミングが発生することもあるため、特に注意して扱うこと。

dedentは非常に便利なツールだが、使い方を誤ると意図しないフォーマットで出力される原因となるため、しっかりとテストしてから運用することが望ましい。

参考リンク