質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

1回答

288閲覧

processingでオブジェクトの配列を交換したい

nanako_o

総合スコア1

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

1グッド

0クリップ

投稿2024/01/26 04:07

実現したいこと

オブジェクトの入ってる配列をループで動かしていきたいです。

発生している問題・分からないこと

staff.xには情報とx座標がはいっています。staff.positionはwindowをmember2でわったx座標が、格納されています。
staff.xは移動する情報でstaff.positionはその情報をしまう箱のような役割をしています。この情報を箱にしまうループがうまくいきません。
forループでは、配列であらわすと、例えばint data【5】={1,2,3,4,5}があったとして、キーボードで要素数の1を入力したら1,3,4,5,2,というようにループでずれ、次にキーボードで0を入力したら、3,4,5,2,1となります。
つまり、入力された数字が配列の末尾にいき、入力された数字より後ろが前倒しになるということです。
このとき入力される数字はclickedIndexになります、この動きがうまくいきません。
また、
int []data=new int[member2-clickedIndex+1];のmember2-clickedIndex+1というのは先程例に上げた配列の要素数がmember2にあたり、キーボードで入力したものがclickedIndexにあたるので、clickedIndex以降の数字をループで動かすために
int []data=new int[member2-clickedIndex+1];となっております。
プログラムではstaff.position[j]に入ってるstaff.xを見つけ出して、別の箱に移動させらるように準備をしています。

この箱の移し替えの作業が例に上げた配列のループのように動かすにはどうしたらいいでしょうか?

プログラム初心者で言葉足らずなとこもありますがよろしくお願いいたします。

該当のソースコード

processing

1void setX() { 2 int j=0; 3 int []data=new int[member2-clickedIndex+1]; 4 if (clickedIndex!=-1) { 5 6if (clickedIndex < member2 && clickedIndex >= 0) { 7if (staff[clickedIndex].isTimerOn && clickingTimer) { 8 while (j<member2) { 9if (staff[j].position==member2) { 10 int tmp=staff[j].x; 11 for (int k=clickedIndex; 12 k<=member2-1; k++) { 13 for (int i =clickedIndex+1; i <=member2; i++) { 14 if (staff[i].position==k) { 15 data[k]=staff[i].x; 16 } 17 } 18 for (int i=0; i<=member2; i++) { 19 if (staff[i].position==k+1) { 20 data[k]=staff[i].x; 21 } 22 } 23 print(data[k]); 24 } 25 staff[clickedIndex].x=tmp; 2627 j++; 28 } 29 clickingTimer=false; 30 } 31 } 32 } 33}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

GPTや調べてコードを変えてみましたが、交換したいところが初期値から動かなかったり、交換してほしいところに表示されません。

補足

説明が難しく伝わっわてない部分もあるかもしれませんがどうかお願いいたします。

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2024/01/28 11:19

解決したあるいは解決の目途がついたならば、質問を「解決済」にしてください。 参考になった回答をベストアンサーするか、 [ヘルプ|質問を解決済みにしたい](https://teratail.com/help#resolve-question) 回答をヒントにコードを改善した等の場合は自己回答でも結構です。 [ヘルプ|質問をした後に自己解決してしまった](https://teratail.com/help#resolve-myself) その際は他サイトにも同様の回答をするか、このページのリンクを貼ってください(未解決の質問は誰か考えているかもしれず、回答したら「実は別のサイトで解決していました」ではガッカリしますので) もちろん目途がついていないなら安易に「解決済」にせず、回答への疑問点や不明点をお気軽にコメントください^^ (「未解決」のまま放置されるのは困りますが)「解決済」を急かすつもりはありません。 あるいはもっと良い回答が付くかもしれませんw
nanako_o

2024/01/28 15:10 編集

色々教えてくださり、ありがとうございます。 知恵袋は解決済みにしました。 話はプログラミングの方にもどしますが、教えてくださったコードを参考にして書き換えてみました。 いままでオブジェクトが思い道理に全く動きませんでしたが、はじめてクリックした箇所が後ろに回るループがうまく行きました! 本当にありがとうございます。 ただ、clickedIndex+1からmember2までを前倒しにしたいのですが、どうしてもmember2より前からしかループにはいってくれません。 ループの動きは完璧なのですが、、 以下にコードをはります。 void setX() { if (clickedIndex!=-1) { // ボディ側だったら if (clickedIndex <= member2 && clickedIndex >= 0) { if (staff[clickedIndex].isTimerOn && clickingTimer) { Staff tmp = staff[clickedIndex]; for (int i = clickedIndex+1; i <member2; i++) { staff[i - 1] = staff[i]; } staff[member2-1] = tmp; print(1); int[] xx = new int[member2]; // x用の配列を用意 for (int i = 0; i < xx.length; i++) { xx[i] = staff[i].x; // 詰める } //printstaff(xx); xx = sort(xx); // ソート //printstaff(xx); for (int i = 0; i < xx.length; i++) { staff[i].x = xx[i]; // 詰め直し } } } } } staff[member2-1] = tmp;この部分をmember2に変えてみたのですが、それだとループが一切動かなくなってしまいます。 どうしたらいいでしょうか?
guest

回答1

0

ベストアンサー

例えばint data【5】={1,2,3,4,5}があったとして、キーボードで要素数の1を入力したら1,3,4,5,2,というようにループでずれ、次にキーボードで0を入力したら、3,4,5,2,1となります。

字面通り素直に書くならこうでしょうか。

Processing

1int[] array = { 1, 2, 3, 4, 5 }; 2 3int index = 1; 4int tmp = array[index]; 5for(int i = index + 1; i < array.length; i++){ 6 array[i - 1] = array[i]; 7} 8array[array.length - 1] = tmp; 9println(array); 10println(); 11 12index = 0; 13tmp = array[index]; 14for(int i = index + 1; i < array.length; i++){ 15 array[i - 1] = array[i]; 16} 17array[array.length - 1] = tmp; 18println(array);
[0] 1 [1] 3 [2] 4 [3] 5 [4] 2 [0] 3 [1] 4 [2] 5 [3] 2 [4] 1

ループの代わりにarrayCopyを使うこともできます。

Processing

1//for(int i = index + 1; i < array.length; i++){ 2// array[i - 1] = array[i]; 3//} 4arrayCopy(array, index + 1, array, index, array.length - index - 1);

arrayCopy() / Reference / Processing.org


ただこの要件ならリスト(IntList等)のほうがはるかに簡単です(まあいろいろ罠もありますが^^;

Processing

1IntList list = new IntList(1, 2, 3, 4, 5); 2 3int index = 1; 4int tmp = list.remove(index); // index番目を削除しその値を返す 5list.append(tmp); // 末尾に追加 6println(list); 7println(); 8 9index = 0; 10list.append(list.remove(index)); // 1行でもok 11println(list); 12 13 14// intじゃなくて何かのクラスだった場合 15//import java.util.List; 16 17//ArrayList<Integer> list = new ArrayList<>(List.of(1, 2, 3, 4, 5)); 18 19//int index = 1; 20//int tmp = list.remove(index); // index番目を削除しその値を返す 21//list.add(tmp); // 末尾に追加 22//println(list); 23//println(); 24 25//index = 0; 26//list.add(list.remove(index)); // 1行でもok 27//println(list);

IntList / Reference / Processing.org
ArrayList / Reference / Processing.org


この箱の移し替えの作業が例に上げた配列のループのように動かすにはどうしたらいいでしょうか?

実際はintの配列ではなくStaffクラスの配列ということはわかりますが、xpositionの関係が全く分かりません。

  • 動く図形の上下関係(Z-order)のようなもの??
  • 選んだトランプを右端に回すような処理??

交換したいところが初期値から動かなかったり、交換してほしいところに表示されません。
説明が難しく伝わっわてない部分もあるかもしれませんがどうかお願いいたします。

言葉で説明が難しければintの例と同じように、初期値と期待値を例示するとか(↓のような)

staff[0][1][2][3][4]
x12345
position

clickedIndex = 1

staff[0][1][2][3][4]
x13452
position

clickedIndex = 0

staff[0][1][2][3][4]
x34521
position

あるいは今問題になっている部分を極々単純化した、実行できるプログラムを提示いただけると話が通じやすいです。


追記 配列がそのまま並び順になるように変更できないでしょうか?(例えばこんな)

Processing

1Card[] cards = { 2 new Card(5, #ff0000), 3 new Card(65, #00ff00), 4 new Card(125, #0000ff), 5 new Card(185, #ffff00), 6 new Card(245, #00ffff) 7}; 8 9void setup() { 10 size(300, 200); 11} 12 13void draw() { 14 background(255); 15 16 for (int i = 0; i < cards.length; i++) { 17 fill(cards[i].c); 18 rect(cards[i].x, 75, 50, 50); 19 } 20} 21 22void mouseClicked() { 23 // mouseXを雑にcardsインデックス(0~4)に変換 24 int index = int(map(mouseX, 0, width, 0, 5)); 25 println(index); 26 27 // 選択カードを配列の末尾に移動 28 Card tmp = cards[index]; 29 for (int i = index + 1; i < cards.length; i++) { 30 cards[i - 1] = cards[i]; 31 } 32 cards[cards.length - 1] = tmp; 33 34 int[] xx = new int[cards.length]; // x用の配列を用意 35 for (int i = 0; i < cards.length; i++) { 36 xx[i] = cards[i].x; // 詰める 37 } 38 xx = sort(xx); // ソート 39 for (int i = 0; i < cards.length; i++) { 40 cards[i].x = xx[i]; // 詰め直し 41 } 42} 43 44class Card { 45 int x; 46 color c; 47 Card(int x, color c) { 48 this.x = x; 49 this.c = c; 50 } 51}

アプリ動画


さらに追記

Processing

1int member2 = 5; 2Staff[] staff = { 3 new Staff(0, "A"), 4 new Staff(50, "B"), 5 new Staff(100, "C"), 6 new Staff(150, "D"), 7 new Staff(200, "E"), 8 new Staff(250, "F"), 9 new Staff(300, "G"), 10 new Staff(350, "H"), 11 new Staff(400, "I"), 12 new Staff(450, "J") 13}; 14 15 16void setup() { 17 size(500, 200); 18 textAlign(CENTER, CENTER); 19 textSize(24); 20} 21 22void draw() { 23 background(255); 24 25 for (int i = 0; i < staff.length; i++) { 26 fill(0); 27 text(staff[i].c, staff[i].x, 75, 50, 50); 28 noFill(); 29 rect(staff[i].x, 75, 50, 50); 30 } 31} 32 33void mouseClicked() { 34 int clickedIndex = int(map(mouseX, 0, width, 0, 10)); 35 println("clickedIndex:" + clickedIndex); 36 37 if (clickedIndex <= member2 && clickedIndex >= 0) { 38 Staff tmp = staff[clickedIndex]; // clickedIndex番目をとっておく 39 for (int i = clickedIndex + 1; i <= member2; i++) { // clickedIndexの次からmember2番目も含め回す 40 staff[i - 1] = staff[i]; // 1個前へ 41 } 42 staff[member2] = tmp; // 抜けたmember2番目にはめる 43 44 int[] xx = new int[member2 + 1]; // member2がインデックス(5)なら要素数は+1です(6) 45 //int[] xx = new int[staff.length]; // ややこしくなるぐらいなら全件見てもいいのではないか? 46 for (int i = 0; i < xx.length; i++) { 47 xx[i] = staff[i].x; 48 } 49 50 xx = sort(xx); 51 52 for (int i = 0; i < xx.length; i++) { 53 staff[i].x = xx[i]; 54 } 55 56 printArray(staff); // 配列表示 57 } 58} 59 60 61class Staff { 62 int x; 63 String c; 64 Staff(int x, String c) { 65 this.x = x; 66 this.c = c; 67 } 68 @Override String toString() { // toStringとprintArrayでデバッグしやすくなる 69 return c + " x:" + x; 70 } 71}

デバッグ動画

投稿2024/01/26 09:10

編集2024/02/03 07:28
TN8001

総合スコア9326

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nanako_o

2024/01/26 10:36

回答ありがとうございます。 表に書くと以下のようになります。 staff  [0] [1] [2] [3] [4] x    1  2 3 4 5 position 1 2 3 4 5 clickedIndex = 1 ↓ staff [0] [2] [3] [4] [1] x 1 3 4 5 2 position1 2 3 4 5 clickedIndex = 0 ↓ staff [2] [3] [4] [1] [0] x 3 4 5 2 1 position 1 2 3 4 5 となります。 staff.xの要素数がループで移動するたびに要素吸うごと交換されてるため、staff.positionというオブジェクトをつくりました。 staff.positionは格納するための箱になります。 そのため、staff.positionでj番目にあたるstaff.xを探し出して交換させる必要があります。 説明が下手で本当にすみません。 よろしくお願いいたします。
TN8001

2024/01/26 11:20 編集

例えばint[] data ={1,2,3,4,5}を clickedIndex = 1 したら 1,3,4,5,2 なんですよね? [0] [1] [2] [3] [4] ←dataのインデックス 1 2 3 4 5 ←インデックス番目の値 clickedIndex = 1 ↓ [0] [1] [2] [3] [4] ←data[1]の値2が、配列の最後になり抜けた分は詰める 1 3 4 5 2 > staff [0] [2] [3] [4] [1] > x 1 3 4 5 2 > position1 2 3 4 5 インデックスのほうが動いてしまうと意図が分からないです。。。 インデックス順に並び変えるとこうですが、 staff [0] [1] [2] [3] [4] x 1 2 3 4 5 position 1 5 2 3 4 xは常にインデックス+1なので必要ないような? positionは逆にdata[1]に配列の最後の値(5)を入れ、右にずらすような動作ってことでしょうか?? そもそも図の理解の前提が違いますか? > staff.xの要素数がループで移動するたびに要素吸うごと交換されてるため、staff.positionというオブジェクトをつくりました。 > staff.positionは格納するための箱になります。 元の順番を保持するような変数なのかなって気はしますが、すいませんがまだ意味が分かりません。 今何を作っていてこの処理がどう使われるのかを説明できませんか?
nanako_o

2024/01/26 12:15

説明が下手ですみません。 staff.xをループにいれたときにstaff.xの中身を交換したいのですが、どうも要素数ごと動いてしまいます。 それがどうしてかは私にもわかりませんでした、、 そのためstaff.positionをつくりました。 positionは一切動かないようにプログラムしております。 固定された箱と認識して頂きたいです。 staff.xの入力された値の要素数番目を配列の末尾に持っていきたいため、入力された要素数番目のstaff.xをpositionで前から何番目にいるのか探しています。 このときのstaff.x要素数で呼び出してしまうと最初のループはうまく行きますが、それ以降が要素数が動いてしまうのでstaff.xの要素数0が先頭にいるとは限らないということです。 そのためpositionで探します。 今作っているのはアルバイト先のエステティシャンをローテーションで管理するツールです。 担当のエステティシャンが仕事に入ったら列の一番うしろにそのエステティシャンは入るというようにプログラムしたいです。 また説明で理解できないところがあったら行ってください。 よろしくお願いいたします。
TN8001

2024/01/26 14:14

あぁ、わかったかもしれません。 配列の要素を入れ替えるのではなく、要素はそのまま`x`だけが変わるようなイメージですかね? 並び順がxを見ないとわからないとなると、単純な入れ替え処理では並び替えられないような気がします(だから詰まっているんでしょうけど^^; 配列がそのまま並び順になるように変更できないでしょうか?(回答に追記) クラスにxが必要だとしても配列を入れ替えたうえで、別途取得したxをソートし入れなおすようなアプローチのほうが分かりやすい気がします。
nanako_o

2024/01/26 14:21 編集

そうです!!!!はじめて理解してくれる人に出会いました!! おお、、その手がありましたか、、 かなり長い間この問題でつまずいていたので、新たなアプローチ方を知れて嬉しいです。 試してみます。 ありがとうございます!!! また何かあったらコメントさせてください、、
TN8001

2024/01/26 14:45

> かなり長い間この問題でつまずいていたので、新たなアプローチ方を知れて嬉しいです。 そうですかよかったです^^ 「xをソートし入れなおすようなアプローチ」に回答コードを変更しました。 > また何かあったらコメントさせてください、、 もちろんお気軽にどうぞ^^
TN8001

2024/01/28 15:53

回答への質問は回答のコメント欄にお願いします。 > ただ、clickedIndex+1からmember2までを前倒しにしたいのですが、どうしてもmember2より前からしかループにはいってくれません。 このループのことですか? for (int i = clickedIndex + 1; i < member2; i++) { staff[i - 1] = staff[i]; } i < member2 としてるので、当然member2より前ということになります。 member2はstaff.lengthと違うんですかね? こういうことでしょうか?(<じゃなくて<=) for (int i = clickedIndex + 1; i <= member2; i++) { あるいはmember2を全部staff.lengthに置き換えるかでしょうか?
nanako_o

2024/02/03 05:48 編集

コメントが遅くなってしまい、申し訳ありません。 上にあるもう一つのコメントを見ていたため気づくのに時間がかかってしまいました。 member2を=つけて試しても見ましたが、member2より前からしか動きませんでした。 staff.lengthはmember2と別物になります。
TN8001

2024/02/03 07:28

> staff.lengthはmember2と別物になります。 member2の役割がよくわかりません。 staff.lengthはもっと多くて、member2はそれより小さいのでしょうか? 0 1 2 3 4 5 6 7 8 9 ←インデックス A B C D E F G H I J ←入ってるオブジェクト lengthは10 clickedIndexは2 member2は5 だとすると clickedIndex 2のCを引っこ抜いてDEFが前倒しになり、あいたところにCが入る A B D E F C G H I J こうなるってことでしょうか? さらに追記しました。 そうではない場合どういう結果を期待しているかを書いてください。
nanako_o

2024/02/04 08:54

>0 1 2 3 4 5 6 7 8 9 ←インデックス A B C D E F G H I J ←入ってるオブジェクト lengthは10 clickedIndexは2 member2は5 だとすると clickedIndex 2のCを引っこ抜いてDEFが前倒しになり、あいたところにCが入る A B D E F C G H I J こうなるってことでしょうか? そのとおりです。 しかしmember2より前からしか動かないという状況になります。 期待している結果は回答者様が出してくださって例がまんま期待している結果です。 よろしくお願いいたします。
TN8001

2024/02/04 10:03 編集

> そのとおりです。 > しかしmember2より前からしか動かないという状況になります。 詳しくは追記コードを動かして確認していただきたいのですが member2番目が入れ替わらないことは↓の問題(< と <=)で、 > // clickedIndexの次からmember2番目も含め回す > for (int i = clickedIndex + 1; i <= member2; i++) { ここも-1だとおかしくなります。 > staff[member2] = tmp; // 抜けたmember2番目にはめる さらにここの+1がないとxのソートが届かない(member2番目になったCのxが変わらない)ので(順番は入れ替わっているが)見た目の位置は動かないことになります。 > // member2がインデックス(5)なら要素数は+1です(6) > int[] xx = new int[member2 + 1]; 文字で書くとなんのこっちゃという感じですが^^; 追記コードそのままと < と <=の場合・+-1の有り無し等のコードを2窓で同時に実行し、コンソールをよくよく見比べれば「あぁ、なるほどね」ってなると思います^^
nanako_o

2024/02/05 03:43

詳しく教えていただきありがとうございます。 回答者様が教えてくださった部分を修正したら無事に動かすことができました。 何度質問しても丁寧に答えてくださって本当にありがとうございます! なんとか正常に動かせるようになってよかったです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問