アプリ版:「スタンプのみでお礼する」機能のリリースについて

いつもお世話になっています。
オブジェクト配列の各メンバを任意の式で評価して、その評価値が最大のオブジェクトを返す関数はありますか。

例えば、オブジェクト配列の各メンバが、二次元の位置情報を持っているとして、現在地からの直線距離が最も近いオブジェクトを取得する処理を、なるべく短いコードで書くにはどうすればよいですか。

A 回答 (2件)

こんにちは



「オブジェクト配列」と言っているのは
  [ { x:10, y:10 }, { x:50, y:50 }, ・・・]
のような構造の配列として解釈しました。

方法はいろいろと考えられると思いますので、以下は一例です。

>任意の式で評価して、その評価値が最大のオブジェクトを返す関数
任意の式を引数として渡すようにしておけば良いと思いますが、評価式の中で使用する係数などをどのように参照するかのルールが必要そうに思います。
共通のスコープの変数にしてしまえば簡単ですが、ちょっと気持ち悪いので・・・

以下では、係数等も引数にすることにして、評価式には this値として渡す方式をとっています。
係数等が複数の場合も考慮して配列にしていますので、評価式からの参照が少し面倒ですけれど。
また、最大値のオブジェクトが複数存在する場合もあるので、戻り値も同じ構造の配列にしています。

const SelectMax = (o, f, ...p) => {
const v = o.map(f, p), x = Math.max(...v);
return v.map((e, i) => [e, i]).filter( e => e[0] == x).map( e => obj[e[1]]);
};

>なるべく短いコードで書くにはどうすればよいですか。
一般化の度合いを減じたり、パラメータは共通スコープにするなどとすれば、少しは短くすることが可能と思います。

※ 関数の妥当性やオブジェクトの値が計算可能であることなどのチェックは一切行っていませんので、妙な値や妙な関数を与えればエラーになる可能性があります。

◆実行例
const obj = [
{name: "hoge", x:10, y:10 },
{name: "fuga", x:10, y:5 },
{name: "piyo", x:20, y:50 },
{name:"pesha", x:30, y:10 },
{name:"gutya", x:50, y:20 }
];
const p = {x:0, y:0};
const func = function(e) {return (this[0].x - e.x)**2 + (this[0].y - e.y)**2; }

console.log( SelectMax( obj, func, p) );
//結果: [ {name: 'piyo', x: 20, y: 50}, {name: 'gutya', x: 50, y: 20} ] 

※ 定点p(0, 0)からの距離が一番遠い点を求めていますが、同じ距離の点が2か所返されます。
    • good
    • 0
この回答へのお礼

なるほど戻り値が複数になる事を考慮していませんでした。
よって、そのような組み込みの関数が用意されていないのも納得です。

相対的な距離が分かれば良いのでMath.sqrt()は不要でしたね。
これは盲点でして、コードの簡略化に直結するのでうれしいです。

お礼日時:2023/05/20 23:34

var f = (p,c) => (任意式(p)<任意式(c))? c: p;


var 評価値が最大のオブジェ = オブジェ配列.reduce(f);

参考)
https://developer.mozilla.org/ja/docs/Web/JavaSc …
    • good
    • 0
この回答へのお礼

ありがとうございます。
maxやminのようなお手軽な関数は用意されておらず、あくまで比較用のコードを自分で書く必要がある事が分かりました。
満足です。

お礼日時:2023/05/20 23:52

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!