1

Let's say I have the following arrays:

var array_full = ['table', 'sleeping', 'data'];
var array_part = ['sleep', 'able'];

Now, I want to filter out items from the array with full strings (array_full) if they contain items from the array with partial strings (array_part).

I can do it like this:

var rez = [];
for (p in array_part) { 
    array_full.filter(function(f) { if (f.indexOf(array_part[p]) > -1) {rez.push(f)} } ) 
}

But I'm sure there is a better way, isn't it?

EDIT: Thanks to all!

A S
  • 1,195
  • 2
  • 12
  • 26

5 Answers5

2

You could use some and includes like this:

const array_full = ['table', 'sleeping', 'data'];
const array_part = ['sleep', 'able'];

const output = array_full.filter(a => array_part.some(b => a.includes(b)))

console.log(output)

includes and arrow functions are ES2015+ syntax. If you want ES5, you could do something like this

var array_full = ['table', 'sleeping', 'data'];
var array_part = ['sleep', 'able'];

var output = array_full.filter(function(a) {
  return array_part.some(function(b) {
    return a.indexOf(b) > -1
  })
})

console.log(output)
adiga
  • 34,372
  • 9
  • 61
  • 83
2

If your use case is really about looking for strings in strings :

you can build a regular expression from array_part

LeGEC
  • 46,477
  • 5
  • 57
  • 104
2

var array_full = ['table', 'sleeping', 'data'];
var array_part = ['sleep', 'able'];

var rez = array_full.filter(item => array_part.some(str => item.includes(str)));
console.log(rez);
PopHip
  • 700
  • 6
  • 23
1

You could filter the array and look for part includes with

var array_full = ['table', 'sleeping', 'data'],
    array_part = ['sleep', 'able'],
    result = array_full.filter(s => array_part.some(p => s.includes(p)));

console.log(result);

Maintaing the order of array_part with a Set, because otherwise you could get mot than one item of array_full.

var array_full = ['table', 'sleeping', 'data'],
    array_part = ['sleep', 'able'],
    result = Array.from(array_part.reduce(
        (r, p) => array_full.reduce((q, s) => s.includes(p) ? q.add(s) : q, r),
        new Set
    ));

console.log(result);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Sorry for a delayed follow up, but what if I need to filter out those `array_full` items according to the order provided `array_part`? Like, `['sleeping', 'table']`, not `['table', 'sleeping']`. Iterating over the `array_part` list, as done in the post, obviously allows that. But not your otherwise nice oneliner, unfortunately. Any workaround may be? Thanks :) – A S May 22 '19 at 11:26
  • 1
    it is a bit more complicated. do you have only one matching item? – Nina Scholz May 22 '19 at 11:38
  • Sorry, what do you mean by "one matching item"? `array_part` has two items, which partially match items in `array_full`... – A S May 22 '19 at 11:43
  • Oh, is it possible that an item from `array_part` matches more than 1 item in `array_full`? Then no, that's not possible. – A S May 22 '19 at 11:46
  • 1
    ad 2 and in which order do you want then? – Nina Scholz May 22 '19 at 11:46
  • In the same order those partial matches are listed in `array_part`. If `array_part = ['sleep', 'able']`, then the result should be `['sleeping', 'table']`. – A S May 22 '19 at 11:48
  • 1
    please see edit. – Nina Scholz May 22 '19 at 11:58
1

If you know the partial words are made of word characters and don't contain characters special to regular expressions like (*, $ . etc...), you could compile array_part into a regex:

var array_full = ['table', 'sleeping', 'data'];
var array_part = ['sleep', 'able'];

let rx = new RegExp(array_part.join('|'))
console.log(array_full.filter(w => rx.test(w)))
Mark
  • 90,562
  • 7
  • 108
  • 148