JavaScript配列で、要素のすべてのインスタンスのインデックス(「Nano」など)を見つけようとしています。
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
私はjQuery.inArrayまたは同様に.indexOf()を試しましたが、要素の最後のインスタンスのインデックス(この場合は5 )しか与えられませんでした。
すべてのインスタンスでどのように取得できますか?
JavaScript配列で、要素のすべてのインスタンスのインデックス(「Nano」など)を見つけようとしています。
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
私はjQuery.inArrayまたは同様に.indexOf()を試しましたが、要素の最後のインスタンスのインデックス(この場合は5 )しか与えられませんでした。
すべてのインスタンスでどのように取得できますか?
回答:
この.indexOf()
メソッドには、検索を開始するインデックスを指定するオプションの2番目のパラメーターがあるため、ループでそれを呼び出して、特定の値のすべてのインスタンスを見つけることができます。
function getAllIndexes(arr, val) {
var indexes = [], i = -1;
while ((i = arr.indexOf(val, i+1)) != -1){
indexes.push(i);
}
return indexes;
}
var indexes = getAllIndexes(Cars, "Nano");
インデックスの使用方法を明確にしていないため、関数はそれらを配列として返します(または、値が見つからない場合は空の配列を返します)が、個々のインデックス値を使用して別のことを行うことができますループの内側。
更新:VisioNのコメントによると、単純なforループは同じ仕事をより効率的に実行し、理解しやすく、したがって保守が容易になります。
function getAllIndexes(arr, val) {
var indexes = [], i;
for(i = 0; i < arr.length; i++)
if (arr[i] === val)
indexes.push(i);
return indexes;
}
.indexOf()
と述べたので、それが機能することを示したかったのです。(私は、OPがforループでそれを行う方法を理解できると思いました。)もちろん、他の方法もあります。たとえば、Cars.reduce(function(a, v, i) { if (v==="Nano") a.push(i); return a; }, []);
indexes
代わりにindices
P:
別の代替ソリューションは、使用することArray.prototype.reduce()
です:
["Nano","Volvo","BMW","Nano","VW","Nano"].reduce(function(a, e, i) {
if (e === 'Nano')
a.push(i);
return a;
}, []); // [0, 3, 5]
:)
ええ、私はおそらくreduce
良い代替案になると思いました。
array.reduce((a, e, i) => (e === value) ? a.concat(i) : a, [])
contat
が遅いpush
ので、答えに固執します。
Array.prototype.map()およびArray.prototype.filter()を使用した別のアプローチ:
var indices = array.map((e, i) => e === value ? i : '').filter(String)
map(…)
平等のための各反復でチェックe
してvalue
。それらがインデックスと一致する場合は返され、それ以外の場合は空の文字列です。これらの偽の値を取り除くにはfilter(String)
、結果に文字列型の値のみが含まれ、空ではないことを確認してください。filter(String)
:のように書くこともできたfilter(e => e !== '')
es6スタイルでより簡単な方法。
const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);
//Examples:
var cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
indexOfAll(cars, "Nano"); //[0, 3, 5]
indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []
map
との両方を使用して、これに対する簡単で読み取り可能なソリューションを作成できますfilter
。
const nanoIndexes = Cars
.map((car, i) => car === 'Nano' ? i : -1)
.filter(index => index !== -1);
編集:IE / Edgeをサポートする必要がない場合(またはコードをトランスパイルしている場合)、ES2019から提供されたflatMapを使用すると、簡単な1 行でこれを実行できます。
const nanoIndexes = Cars.flatMap((car, i) => car === 'Nano' ? i : []);
注:MDNは、whileループを使用するメソッドを提供します。
var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.indexOf(element);
while (idx != -1) {
indices.push(idx);
idx = array.indexOf(element, idx + 1);
}
他の回答よりも優れているとは言えません。ただ興味があるだけ。
const indexes = cars
.map((car, i) => car === "Nano" ? i : null)
.filter(i => i !== null)
これは私のために働きました:
let array1 = [5, 12, 8, 130, 44, 12, 45, 12, 56];
let numToFind = 12
let indexesOf12 = [] // the number whose occurrence in the array we want to find
array1.forEach(function(elem, index, array) {
if (elem === numToFind) {indexesOf12.push(index)}
return indexesOf12
})
console.log(indexesOf12) // outputs [1, 5, 7]
別の方法を共有するために、関数ジェネレーターを使用して結果を取得することもできます。
function findAllIndexOf(target, needle) {
return [].concat(...(function*(){
for (var i = 0; i < target.length; i++) if (target[i] === needle) yield [i];
})());
}
var target = "hellooooo";
var target2 = ['w','o',1,3,'l','o'];
console.log(findAllIndexOf(target, 'o'));
console.log(findAllIndexOf(target2, 'o'));
スタックを使用して、条件「arr [i] == value」に遭遇するたびに「i」をスタックにプッシュできます。
これをチェックして:
static void getindex(int arr[], int value)
{
Stack<Integer>st= new Stack<Integer>();
int n= arr.length;
for(int i=n-1; i>=0 ;i--)
{
if(arr[i]==value)
{
st.push(i);
}
}
while(!st.isEmpty())
{
System.out.println(st.peek()+" ");
st.pop();
}
}
javascript
いますが、あなたの答えはJava
私が信じていますか?
ポリフィルを使用できます
if (!Array.prototype.filterIndex) {
Array.prototype.filterIndex = function (func, thisArg) {
'use strict';
if (!((typeof func === 'Function' || typeof func === 'function') && this))
throw new TypeError();
let len = this.length >>> 0,
res = new Array(len), // preallocate array
t = this, c = 0, i = -1;
let kValue;
if (thisArg === undefined) {
while (++i !== len) {
// checks to see if the key was set
if (i in this) {
kValue = t[i]; // in case t is changed in callback
if (func(t[i], i, t)) {
res[c++] = i;
}
}
}
}
else {
while (++i !== len) {
// checks to see if the key was set
if (i in this) {
kValue = t[i];
if (func.call(thisArg, t[i], i, t)) {
res[c++] = i;
}
}
}
}
res.length = c; // shrink down array to proper size
return res;
};
}
次のように使用します。
[2,23,1,2,3,4,52,2].filterIndex(element => element === 2)
result: [0, 3, 7]
findIndex
コールバック出力に一致する最初のインデックスのみを取得します。findIndexes
Arrayを拡張して独自の配列を実装し、配列を新しい構造にキャストできます。
class EnhancedArray extends Array {
findIndexes(where) {
return this.reduce((a, e, i) => (where(e, i) ? a.concat(i) : a), []);
}
}
/*----Working with simple data structure (array of numbers) ---*/
//existing array
let myArray = [1, 3, 5, 5, 4, 5];
//cast it :
myArray = new EnhancedArray(...myArray);
//run
console.log(
myArray.findIndexes((e) => e===5)
)
/*----Working with Array of complex items structure-*/
let arr = [{name: 'Ahmed'}, {name: 'Rami'}, {name: 'Abdennour'}];
arr= new EnhancedArray(...arr);
console.log(
arr.findIndexes((o) => o.name.startsWith('A'))
)
アンダースコア/ロダッシュを使用する場合は、次のようにすることができます
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
_.chain(Cars).map((v, i)=> [i, v === "Nano"]).filter(v=>v[1]).map(v=>v[0]).value()
[0, 3, 5]
(["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"]).map((v, i)=> [i, v === "Nano"]).filter(v=>v[1]).map(v=>v[0])
for
、インデックス配列にデータを入力する単一のループに代わる高速な方法ではないようです。