{ }codelper

学ぶ › TypeScript

データ · 13

リストの編集

含むか調べる、取り除く、逆にする、入れ替える、同じ値で埋める、コピー。

リストは作ったあとでも、値を取り除いたり順番を変えたりできます。
下の例はカードのリストをコピーしておき、ある数が入っているか調べて、あれば取り除き、先頭のカードを取り除き、逆順にし、先頭の2枚を入れ替えます。
そして編集したリスト、コピーしておいた元のリスト、0 で埋めた新しいリストを表示します。

import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").trim().split("\n");const cards: number[] = lines[1].trim().split(/\s+/).map(Number);const x: number = Number(lines[2]);const original: number[] = [...cards]; // 복사해 둬요if (cards.includes(x)) {  console.log("yes");  cards.splice(cards.indexOf(x), 1); // 값으로 빼기: 자리를 찾아서 하나만} else {  console.log("no");}cards.splice(0, 1); // 자리로 빼기: 0번cards.reverse();[cards[0], cards[1]] = [cards[1], cards[0]]; // 자리 바꾸기const blank: number[] = new Array<number>(cards.length).fill(0); // 0으로 채운 새 목록console.log(cards.join(" "));console.log(original.join(" "));console.log(blank.join(" "));
stdin
5
30 10 40 10 50
10
stdout
yes
10 50 40
30 10 40 10 50
0 0 0

ポイント

  • 含むか調べると、真か偽で答えが返ります。
    ループで一つずつ比べなくても1行で書けます(C はループで探します)。
  • 取り除く方法は二つあります。
    位置で取り除くと i 番の枠がなくなり、値で取り除くとその値が最初に出てくる枠一つだけがなくなります。
    どちらも後ろの値が一つずつ前に詰まります。
    ない値を取り除こうとしたときに起きることは言語によって違います。
  • 逆にする操作は、新しいリストを作らず、そのリストの順番を反対にします。
  • 入れ替え:二つの枠の値を入れ替えるとき、a[0] = a[1] から書くと a[0] の元の値が消えます。
    一時変数に片方を移しておくか、一度に入れ替える書き方を使います。
  • 同じ値で埋める:0 が n 個入ったリストのように、大きさと最初の値だけを渡してリストを作ります。
  • コピー:08 の単元で、b = a は同じリストに名前をもう一つ付けるだけだと学びました。
    元のリストを残したいときは、編集する前に別にコピーします。
    Python・JavaScript・Java・C#・Craykon のこのコピーは1段だけです。
    リストの中にリストが入った格子(12 の単元)は、コピーしても行は共有されたままなので、行ごとに別々にコピーします。

言語ごとの書き方

Pythonx in a。
値では a.remove(x)(なければ ValueError)、位置では a.pop(i) か del a[i]。
a.reverse()。
a[0], a[1] = a[1], a[0]。
[0] * n。
コピーは a.copy()
JavaScripta.includes(x)。
位置では a.splice(i, 1)。
値で取り除く関数はないので、a.indexOf(x) で位置を探して splice。
a.reverse()。
[a[0], a[1]] = [a[1], a[0]]。
new Array(n).fill(0)。
コピーは [...a]
TypeScriptJavaScript と同じです
JavaList<Integer> で a.contains(x)。
位置では a.remove(i)、値では a.remove(Integer.valueOf(x))(なければ false)。
Collections.reverse(a)、Collections.swap(a, 0, 1)。
new ArrayList<>(Collections.nCopies(n, 0))。
コピーは new ArrayList<>(a)。
配列 new int[n] は最初から 0 で埋まっています
C#List<int> で a.Contains(x)。
値では a.Remove(x)(なければ false)、位置では a.RemoveAt(i)。
a.Reverse()。
(a[0], a[1]) = (a[1], a[0])。
Enumerable.Repeat(0, n).ToList()。
コピーは new List<int>(a)
C++std::find(a.begin(), a.end(), x) が a.end() でなければ入っています。
見つけた位置は a.erase(it)、i 番は a.erase(a.begin() + i) で取り除きます。
std::reverse(a.begin(), a.end())、std::swap(a[0], a[1])。
std::vector<int> b(n, 0)。
b = a がそのままコピーです
C配列は大きさが決まっていて、こうした関数はありません。
ループで探し、取り除くときは後ろの値を一つずつ前に詰めて、個数を自分で減らします。
逆順は両端から入れ替え、入れ替えは一時変数 t で行います。
コピーは memcpy(b, a, n * sizeof a[0]) — b = a はコンパイルエラーです
Craykona.含む(x)。
値では a.取り除く(x)(なければ false)、位置では a.位置で取り除く(i)。
a.逆に()。
入れ替えは一時変数で。
新リスト(n, 0)。
コピーは a.部分リスト(0, a.個数)

よくある間違い

ない値を取り除こうとしたら最後の値が消えたJavaScript · TypeScript

const a = [1, 2, 3];
a.splice(a.indexOf(9), 1);
console.log(a);

→ [ 1, 2 ] — 値がないと indexOf は -1 を返し、splice(-1, 1) は最後の枠を取り除きます

先にあるか確かめます:const i = a.indexOf(9); if (i !== -1) a.splice(i, 1);

リストを回りながらそのリストから取り除いたPython · JavaScript · TypeScript · Java · C#

a = [1, 1, 2, 3]
for v in a:
    if v == 1:
        a.remove(v)
print(a)

→ Python は [1, 2, 3] — 取り除いた枠に次の値が詰まるので、二つ目の 1 を飛ばします。JavaScript の for...of も同じ結果です。Java は ConcurrentModificationException、C# は InvalidOperationException で止まります。Craykon の それぞれ だけは、始めるときのリストを写し取ってから回るので、1 が二つとも取り除かれて 2 3 になります

残す値だけを集めて新しいリストを作るか、専用の関数を使います:Python a = [v for v in a if v != 1]、JavaScript a = a.filter(v => v !== 1)、Java a.removeIf(v -> v == 1)、C# a.RemoveAll(v => v == 1)。

値 1 を取り除くつもりが 1 番の枠が消えたJava

List<Integer> a = new ArrayList<>(List.of(1, 2, 3));
a.remove(1);
System.out.println(a);

→ [1, 3] — int を渡すと位置で取り除きます。1 番の枠の 2 が消えました

値で取り除くには a.remove(Integer.valueOf(1)) → [2, 3]。
[10, 20, 30] に a.remove(10) と書くと、10 番の枠を探して IndexOutOfBoundsException で止まります。

言語ごとの違い
逆にする操作はそのリスト自体を変える命令なので、結果を受け取って使ってはいけない言語があります。
Python で b = a.reverse() と書くと b は None です。
逆順の新しいリストがほしいときは、Python は a[::-1]、JavaScript はコピーしてから逆にする [...a].reverse() を使います。
また C の int *b = a; はコピーではなく、同じ配列を指す名前です。
b[0] = 9 とすると a[0] も 9 になります。

練習問題