admin管理员组

文章数量:1301528

I have an array that is filtered based on what the user types into a search box..

var x = ["Apple","Pear","Pineapple"];

var value = e.target.value;

var regex = new RegExp(`^${value}`, 'i');

var filtered = x.sort().filter(v => regex.test(v));

If I were to type "P" into the search box the console would print

["Pear","Pineapple"]

What I need however is another array of the original index position of Pear and Pineapple that would print the following

[1,2]

How would I go about achieving this?

I have an array that is filtered based on what the user types into a search box..

var x = ["Apple","Pear","Pineapple"];

var value = e.target.value;

var regex = new RegExp(`^${value}`, 'i');

var filtered = x.sort().filter(v => regex.test(v));

If I were to type "P" into the search box the console would print

["Pear","Pineapple"]

What I need however is another array of the original index position of Pear and Pineapple that would print the following

[1,2]

How would I go about achieving this?

Share edited Jul 24, 2019 at 8:05 ShaneOG97 asked Jul 24, 2019 at 7:59 ShaneOG97ShaneOG97 5302 gold badges11 silver badges27 bronze badges 5
  • where is the regex? – briosheje Commented Jul 24, 2019 at 8:03
  • Forgot to add it, it's in there now – ShaneOG97 Commented Jul 24, 2019 at 8:04
  • Maybe you can use var indices = filtered.map(f => x.indexOf(f));? Since you keep a copy of the original unmodified array in x. – nbokmans Commented Jul 24, 2019 at 8:04
  • and where is 'value'? – briosheje Commented Jul 24, 2019 at 8:04
  • Filter keys instead of values – jank Commented Jul 24, 2019 at 8:06
Add a ment  | 

4 Answers 4

Reset to default 5

You can do that in a single shot using reduce (read more about reduce here). There is no need to filter, you can just generate another array, keep track of the index of the currently looped item (assuming you want the sorted index).

If you don't want the sorted index, just remove .sort. Not sure why it's there in the first place. This solution requires a single iteration, which should be optimal (as long as you remove the unneeded sort).

var x = ["Apple","Pear","Pineapple"];
var value = 'P';
var regex = new RegExp(`^${value}`, 'i');

var filtered = x.sort().reduce((acc, next, i) => { // acc is the current accumulator (initially an empty array), next is looped item, i is item's index (what you want in the result).
  return regex.test(next) && acc.push(i), acc // <-- if the regex test is successfull, `i` is pushed to the accumulator. In both cases (so, even if the regex fails) the accumulator is returned for the next iteration.
}, []); // <-- [] is the initial value of `acc`, which is a new empty array.
console.log(filtered);

Instead of filtering the array, filter the keys of the array instead:

var x = ["Apple","Pear","Pineapple"],
    value ="P",
    regex = new RegExp(`^${value}`, 'i'),
    filtered = [...x.keys()].filter(i => regex.test(x[i]));

console.log(filtered)

keys() method returns a Array Iterator. So, you need to use spread syntax or Array.from() to convert it to an array

You could get first the value/index pairs, filter and get either the values or indices.

Intead of a RegExp, you could use String#startsWith, which has no problems of characters with special meanings.

var array = ["Apple", "Pear", "Pineapple"],
    value = 'P',
    filtered = array
        .sort()
        .map((v, i) => [v, i])
        .filter(([v]) => v.startsWith(value)),
    values = filtered.map(([v]) => v),
    indices = filtered.map(([, i]) => i);

console.log(values);
console.log(indices);

You can get your indexes with indexOf() from the original array like so:

const x = ["Apple","Pear","Pineapple"];

var regex = new RegExp(`^P`, 'i');

const filtered = x.sort().filter(v => regex.test(v));
const filteredIndexes = filtered.map(v => x.indexOf(v));

console.log(filtered);
console.log(filteredIndexes);

You could also use reduce to do it all in one iteration like the so:

const x = ["Apple","Pear","Pineapple"];

var regex = new RegExp(`^P`, 'i');

const [filtered, filteredIndexes] = x.sort().reduce((acc, val, i) => {
  // If the regex fits, add to the arrays
  if(regex.test(val)) {
    // Adding to the array via array spread operator
    acc = [[...acc[0], val],[...acc[1], i]];
  }
  return acc;
}, [[],[]]); // Initial value of accumulator

console.log(filtered);
console.log(filteredIndexes);

本文标签: javascriptOriginal index position after filtering an arrayStack Overflow