FORループを使用せずにこれをどのように書き換えますか?
const a = [2, 5, 78, 4];
const expensiveFunction = n => 2 * n;
let result;
// Find the first number
for (let i = 0; i < a.length; i++) {
const r = expensiveFunction(a[i]);
if (r > 100) {
result = r;
break;
}
}
console.log(result);
私の素朴なアプローチ:
const result = a.map(expensiveFunction).find(x => x > 100);
console.log(result);
しかし、これはすべての要素でexpensiveFunction
を実行します。上記の場合、expensiveFunction(4)
を実行しないでください。
いくつかの言語はfind_map
(e.g、 錆 を持っています、私はLodashでもアンダースコアで見つけられませんでした。
検索にスマートな機能を使用しないのはなぜですか?
let desiredValue;
const result = a.find( x =>{
desiredValue = expensiveFunction(x);
return desiredValue > 100;
});
log( desiredValue );
_
最初の結果を見つけた直後に高価なループを終了します。
ARRAYのブール値(NULL)値を削除するために、3値オペレータを使用して最短の方法を実行して条件とフィルタ()を簡素化することができます。
const a = [2, 5, 78, 100];
const result = a.map((n)=> 2*n > 100 ? 2*n : null ).filter(Boolean)[0];
console.log(result);
_
私が続くアプローチは、「高価な機能」関数を可能な限り少なくとも可能に呼び出す可能性を減らすことです。この目的のために、 'divide and conquerアルゴリズム'を使用しました。配列を半分の部分に分割し、分割要素の高価な機能を呼び出して、どの半分を続行するかを決定します。このステップは100より上にある最小の要素を見つけるまで再帰的に実行します。特に非常に大きなサイズの配列では、この方法では、高価な関数呼び出しを大幅に小さい数に減らすことができます。そのため、「高価な課題」機能はあなたの「高価な機能」を経済的に呼び出すでしょう。アレイは最初にソートする必要があります。
const a = [2, 5,78, 80].sort((a,b) => a-b);
const expensiveFunction = n => 2 * n;
const expensiveFunCaller= ([...arr]) =>{
if(arr.length<2){
let r = expensiveFunction(arr[0]);
if(r>100) return r;
return;
}
else if(arr.length === 2){
let r = expensiveFunction(arr[0]);
if(r>100) return r;
r = expensiveFunction(arr[1]);
if(r>100) return r;
return;
}
let idx = Math.floor(arr.length / 2);
let r = expensiveFunction(arr[idx]);
return (r<100)?expensiveFunCaller(arr.slice(idx+1, arr.length)):expensiveFunCaller(arr.slice(0, idx+1));
}
console.log(expensiveFunCaller(a));
_