funkadelic
funkadelic

Reputation: 93

Search for a subarray in an array in JavaScript

I have an array of Objects:

arrObj : [{ id: 0, text: 'At', start: '15.000' },
      { id: 1, text: 'the', start: '15.492'},
      { id: 2, text: 'left', start: '15.984'},
      { id: 3, text: 'we', start: '16.476' },
      { id: 4, text: 'can', start: '16.967'},
      { id: 5, text: 'see...', start: '17.459' },
      { id: 6, text: 'At', start: '18.166'},
      { id: 7, text: 'the', start: '18.440' }]

I have to search for an array and return the start and end word ids. For example in this case:

["At", "the"]

I have to return [(0,1),(6,7)] I am currently using a for each loop to iterate over the arrObj and see if the words match. I also tried indexOf by joining the objects texts but it returns the char index not array index.

But this does not seem efficient. How can i efficiently search for something like this?

Upvotes: 0

Views: 1759

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386670

A solution for any length of a search array. It stores the index of the search array and increments with a match.

It adds only an array with the indices, if the indices for all items of the search array are found.

var array = [{ id: 0, text: 'At', start: '15.000' }, { id: 1, text: 'the', start: '15.492' }, { id: 2, text: 'left', start: '15.984' }, { id: 3, text: 'we', start: '16.476' }, { id: 4, text: 'can', start: '16.967' }, { id: 5, text: 'see...', start: '17.459' }, { id: 6, text: 'At', start: '18.166' }, { id: 7, text: 'the', start: '18.440' }],
    search = ["At", "the"],
    result = array.reduce(function (i, t) {
        return function (r, a, j) {
            if (search[i] === a.text) {
                t.push(j);
                i++;
                if (i === search.length) {
                    r.push(t);
                    t = [];
                    i = 0;
                };
            }
            return r;
        };
    }(0, []), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

baao
baao

Reputation: 73251

You could use reduce to get the start and end positions in an array:

let arrObj = [{ id: 0, text: 'At', start: '15.000' },
      { id: 1, text: 'the', start: '15.492'},
      { id: 2, text: 'left', start: '15.984'},
      { id: 3, text: 'we', start: '16.476' },
      { id: 4, text: 'can', start: '16.967'},
      { id: 5, text: 'see...', start: '17.459' },
      { id: 6, text: 'At', start: '18.166'},
      { id: 7, text: 'the', start: '18.440' }];

let arr = ["At", "the"];
let res = arrObj.reduce((a, b, i) => {
  let index = arr.indexOf(b.text);
  if (index === 0) {
    a.push(i);
  } else if (index === 1) {
    a.push([a.pop()].concat(i));
  }
  return a;
}, []);

console.log(res);

Note that this will only work if the array with the searchterms holds 2 entries.

If you need more than two searchterms in the array, this will work:

let arrObj = [{ id: 0, text: 'At', start: '15.000' },
      { id: 1, text: 'the', start: '15.492'},
      { id: 2, text: 'left', start: '15.984'},
      { id: 3, text: 'we', start: '16.476' },
      { id: 4, text: 'can', start: '16.967'},
      { id: 5, text: 'see...', start: '17.459' },
      { id: 6, text: 'At', start: '18.166'},
      { id: 7, text: 'the', start: '18.440' }]

let arr = ["At", "the", "left"];
let res = arrObj.reduce((a,b,i) => {
	let index = arr.indexOf(b.text);
  if (index > -1) {
  if (index % arr.length === 0) {
  	a.push(i);
  } else {
  	let tmp = a.pop();
    a.push(tmp instanceof Array ? tmp.concat(i) : [tmp].concat(i));
  }  
  }
  return a;
}, []);
console.log(res);

Upvotes: 1

Related Questions