Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

連想配列 #225

Open
syuilo opened this issue Jan 5, 2023 · 24 comments
Open

連想配列 #225

syuilo opened this issue Jan 5, 2023 · 24 comments
Labels

Comments

@syuilo
Copy link
Collaborator

syuilo commented Jan 5, 2023

オブジェクトとは異なり、任意の値をキーにできる

構文案

let obj = {
  a: 42
}

let map = &{
  1: 42
  "adfadgf": "sdfgsfgsfg"
  obj: "hoge"
}

<: map[obj] // "hoge"
@syuilo syuilo added enhancement New feature or request interpreter parser labels Jan 5, 2023
@syuilo syuilo pinned this issue Jan 5, 2023
@marihachi

This comment was marked as resolved.

@syuilo
Copy link
Collaborator Author

syuilo commented Jan 6, 2023

オブジェクトを書くときにキーをいちいちクオートで囲まなければいけないのが面倒というのがある

@syuilo
Copy link
Collaborator Author

syuilo commented Jan 7, 2023

オブジェクトを書くときにキーをいちいちクオートで囲まなければいけないのが面倒というのがある

面倒という以外にも、AiScriptはJavaScriptで書かれたオブジェクトをそのままコピペ可能にしたいという理念が一応ある

@ikasoba
Copy link
Collaborator

ikasoba commented Sep 9, 2023

それなら任意の値をキーに設定する構文をJSの計算プロパティ名に合わせたほうが良さそう?(/ω・\)チラッ
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Object_initializer#:~:text=%E8%A8%88%E7%AE%97%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E5%90%8D

こんなふうな構文です

&{
  hoge: 1234   // hogeはキー名として設定される
  [obj]: ...   // objは変数として評価され、中に入っている値がキーに設定される
  [1 + 1]: ... // [ ... ] で囲まれたキーは式として評価される
}

@FineArchs
Copy link
Member

  • 配列やオブジェクト、連想配列をキーにする場合はdeep-equalでマッチ判定する?
  • 関数がキーになった場合どうマッチする?
  • JSON.parseの引数にされたら弾く?

@syuilo
Copy link
Collaborator Author

syuilo commented Sep 9, 2023

配列やオブジェクト、連想配列をキーにする場合はdeep-equalでマッチ判定する?

そうね

関数がキーになった場合どうマッチする?

これも↑と同様にdeep-equal判定で良さそう

JSON.parseの引数にされたら弾く?

弾くことはせず、JSON化できないキー/値は除外する感じになりそう

@marihachi marihachi removed the enhancement New feature or request label Oct 13, 2023
@marihachi
Copy link
Contributor

キーワードだけどの&以外にもmaptabledictionaryなども考えられそう

@marihachi
Copy link
Contributor

marihachi commented Nov 5, 2023

配列やオブジェクト、連想配列をキーにする場合はdeep-equalでマッチ判定する?

そうね

参照が一致するかでも良さそうな?a == b
deep-equalやると、パフォーマンスコストが結構ありそうかも (イメージだけど)

@FineArchs
Copy link
Member

参照が一致するかでも良さそうな?

参照一致の連想配列は用途が考えづらいと思う
deep-equalであればコストを差し置いても使いたい場面がいくらかある

@FineArchs
Copy link
Member

FineArchs commented Nov 5, 2023

個人的には普通の比較もdeep-equalに変えたい
参照一致の使い道がわからん

@marihachi
Copy link
Contributor

用途で考えるとそうかも..

@marihachi
Copy link
Contributor

@syuilo 👀

@syuilo
Copy link
Collaborator Author

syuilo commented Nov 6, 2023

deep-eqalで比較したい

@syuilo
Copy link
Collaborator Author

syuilo commented Nov 6, 2023

キーワードはdicとかどうかしら

@marihachi
Copy link
Contributor

deep-equalだと循環してスタックオーバーフローするとか起こる?その辺は大丈夫?

@FineArchs
Copy link
Member

let a=[]
a[0]=a
Json:stringify(a) //Maximum stack size exceeded

これみたいなやつですね
参照一致ならdeep-equalでも一致なのでdeep-equalでの比較の前に参照の比較を挟んでおくとよさそう?

@marihachi
Copy link
Contributor

deep-equalでも参照の比較は行われるみたいです。
もう少し複雑な問題かも

@FineArchs
Copy link
Member

function deepEqual(a: Value, b: Value) {
  if (a.type !== b.type) return false;
  if (a.value === b.value) return true;
  if (['arr', 'obj', 'fn'].includes(a.type)) 各子要素を比較;
  else return false;
}

比較自体はこれでなんとかなる気がしますがそういう話ではなく?

@FineArchs
Copy link
Member

somedic[someobj]が面倒になりそうという問題はありますね
Ison:stringifyを用意して文字列化してからMapに突っ込むのが楽そう?

@marihachi
Copy link
Contributor

marihachi commented Nov 7, 2023

配列やオブジェクト、連想配列をキーにする場合はdeep-equalでマッチ判定する?

普通のdeep-equalの実装だと双方のキー(オブジェクトや配列)がそれぞれ同じように循環参照しているとスタックオーバーフローする問題があります。(無限に再帰してマッチするかが確定しないため)

const x = { n: null };
x.n = x;
const y = { n: null };
y.n = y;
deepEqual(x, y);

@marihachi
Copy link
Contributor

marihachi commented Nov 7, 2023

deep-equalの実装をしてみたので、これで解決できるかも?
この実装だとそれまでに出てきた参照を覚えておくので、同じ参照が出てきた時点で循環してることを検出できます。
e91af8d

@FineArchs
Copy link
Member

FineArchs commented Nov 7, 2023

e91af8d

何故かequal([1], [2])がtrueになるみたいです…何で…?

@marihachi
Copy link
Contributor

marihachi commented Nov 7, 2023

バグ修正しました
これの影響だったかも?

const indexA = refsA.findIndex(x => x === a);

この部分でrefsAを使っていますが、この中に自分自身も含まれているため常に-1以外を返すようになってました。正しくは、自分自身を含む前の状態であるprevRefsAです。

@marihachi
Copy link
Contributor

deep-equalについては多分これでOKそうです
#460

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants