C++ Builder 10.2 Tokyo > JSON > 複数のValueを置換する | 問題点 > 意図しない置換 (連鎖的な失敗)

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3
```

### 処理概要

- JSONオブジェクトのValueを置換したい
    - 用途: 変換元と変換先の文字列が渡されたとき、それに基づきJSONの中身を書換える

### 方針

- ToString()した文字列に対して置換をする
- その結果をJSONオブジェクトとして戻す

### 実装

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *Button1;
	TMemo *Memo1;
	void __fastcall Button1Click(TObject *Sender);
	void __fastcall FormCreate(TObject *Sender);
private:	// ユーザー宣言
	TJSONObject * __fastcall JSON_replaceStrings(TJSONObject *srcPtr, String fromStr, String toStr);
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <DBXJSON.hpp>
#include <memory>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TJSONObject *asrc, *adst;

	asrc = new TJSONObject();

	asrc->AddPair(L"name", L"John Smith");
	asrc->AddPair(L"age", L"33");
	asrc->AddPair(L"place", L"Sydney");
	Memo1->Lines->Add(asrc->ToString());

	String fromstr = "John Smith,33";
	String tostr = "7of9,79";

	adst = JSON_replaceStrings(asrc, fromstr, tostr);

	if (adst != NULL) {
		Memo1->Lines->Add(adst->ToString());
	}

	delete asrc;
	delete adst;
}

TJSONObject * __fastcall TForm1::JSON_replaceStrings(TJSONObject *srcPtr, String fromStr, String toStr)
{
	// 1. parse csv string
	std::unique_ptr<TStringList> fromSL(new TStringList);
	fromSL->StrictDelimiter = true;
	fromSL->DelimitedText = ',';
	fromSL->DelimitedText = fromStr;
	std::unique_ptr<TStringList> toSL(new TStringList);
	toSL->StrictDelimiter = true;
	toSL->DelimitedText = ',';
	toSL->DelimitedText = toStr;

	if (fromSL->Count != toSL->Count) {
		return NULL;  // error
	}

	// 2. replace values
	String replaced = srcPtr->ToString();
	for(int idx=0; idx<fromSL->Count; idx++) {
		String afrom = fromSL->Strings[idx];
		String ato = toSL->Strings[idx];
		replaced = StringReplace(replaced, afrom, ato, TReplaceFlags()<<rfReplaceAll);
	}

	return dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(replaced));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	Memo1->Lines->Clear();
}
//---------------------------------------------------------------------------
```

### 実行例

![2019-05-21_14h30_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/208ddf90-7ddd-b16a-8d5d-4965b51051ae.png)


### 問題点

#### 意図しない置換 (連鎖的な失敗)

`(1,2,3,4,5)`のようなValueを持つ5つのKeyを持つJSONオブジェクトがあるとする。

`(2,3,4,5,6)`に置換するとき、StringReplace()を逐次実施すると'(6,6,6,6,6)`になってしまう場合がある。

1. `(1,2,3,4,5)`
1. `(2,2,3,4,5)`
1. `(3,3,3,4,5)`
1. `(4,4,4,4,5)`
1. `(5,5,5,5,5)`
1. `(6,6,6,6,6)`