14

I'm learning lodash. Is it possible to use lodash to find a substring in an array of strings?

 var myArray = [
 'I like oranges and apples',
 'I hate banana and grapes',
 'I find mango ok',
 'another array item about fruit'
 ]

is it possible to confirm if the word 'oranges' is in my array? I've tried _.includes, _.some, _.indexOf but they all failed as they look at the full string, not a substring

asked Feb 24, 2016 at 23:36
1
  • 1
    Could you join the array into a string and use indexOf? Commented Feb 24, 2016 at 23:38

7 Answers 7

22

You can easily construct an iteratee for some() using lodash's higher-order functions. For example:

_.some(myArray, _.unary(_.partialRight(_.includes, 'orange')));

The unary() function ensures that only one argument is passed to the callback. The partialRight() function is used to apply the 'orange' value as the second argument to includes(). The first argument is supplied with each iteration of some().

However, this approach won't work if case sensitivity matters. For example, 'Orange' will return false. Here's how you can handle case sensitivity:

_.some(myArray, _.method('match', /Orange/i));

The method() function creates a function that will call the given method of the first argument passed to it. Here, we're matching against a case-insensitive regular expression.

Or, if case-sensitivity doesn't matter and you simply prefer the method() approach, this works as well for ES2015:

_.some(myArray, _.method('includes', 'orange'));
answered Feb 26, 2016 at 21:09
Sign up to request clarification or add additional context in comments.

2 Comments

Great explanation of several functions, thank you. I prefer these examples over Alexander Yatkevich's helpful implementation of _.curry, as _.method doesn't require the creation of a separate custom function.
I've noticed one small query with the case insensitive example. If the word 'Orange' was a variable (that could be any word), would we have to escape it before passing it in? i.e something like this (not tested) var myWord = 'Orange'; _.some(myArray, _.method('match', new RegExp(_.escapeRegExp(myWord), "i")));
5

Two quick ways to do it - neither uses lodash (sorry)

var found = myArray.filter(function(el){
 return el.indexOf('oranges') > -1;
}).length;
if (found) { // oranges was found }

or as I mentioned in the comment:

var found = myArray.join(',').indexOf('oranges') > -1;
if (found) { // oranges was found }
answered Feb 24, 2016 at 23:45

2 Comments

Thanks James. These works great. If no-one clarifies a lodash way I'll mark your answer as correct.
The last method is great for most cases, and it works even in old browsers. No need for filter or some.
0

You can do this using lodash, but it's also very doable using native javascript methods:

function stringArrayContains(array, str) {
 function contains(el) {
 return (el.indexOf(str) !== -1) ? true : false;
 }
 return array.some(contains);
}

Testing the above function:

var a = ['hello', 'there'];
var b = ['see', 'ya', 'later'];
stringArrayContains(a, 'ell') // true
stringArrayContains(a, 'what') // false
stringArrayContains(b, 'later') // true
stringArrayContains(b, 'hello') // false

Array.prototype.some applies a function you define to every element of an array. This function (named contains in our case) must return true or false. While iterating through the array elements, if any of the elements returns true, the some method returns true.

Personally, I think in general that if you can use native JS methods for simple functions, it's preferable to loading an library just to do the same thing. Lodash absolutely does have performance benefits, but they aren't necessarily realized unless you're processing large amounts of data. Just my two cents.

Cheers!

answered Feb 24, 2016 at 23:52

Comments

0

The best way is to define a function to check the inclusion of a substring.

var contains = _.curry(function (substring, source) {
 return source.indexOf(substring) !== -1;
});

I use _.curry here to get a curried function, which can be partially applied then.

_.some(myArray, contains('item'));

You can also find a substring in a joined string.

contains('item', _.join(myArray))

UPD:

I have not noticed that lodash already has a function to find value in a collection.

The function _.includes is quite the same to what I defined above. However, as everything in lodash, it uses the different order for arguments. In my example, I put a source as the latest argument for a curried function which makes my function useful for point-free style programming when lodash waits for the source as a first argument of the same function.

Check the Brian Lonsdorf's talk on this matter https://www.youtube.com/watch?v=m3svKOdZijA

Also take a chance to look into ramda. This library provides a better way for practical functional programming in JavaScript.

answered Feb 24, 2016 at 23:58

1 Comment

Thank you for the technique using _.curry, as I am trying to learn the 'lodash approach'
0

I ran into this Question / Answer thread while trying to figure out how to match a substring against each String in an Array and REMOVE any array item that contains that substring.

While the above answers put me on track, and while this doesn't specifically answer the original question, this thread DOES appear first in the google search when you are trying to figure out how to accomplish the above removal of an array item so I figured I would post an answer here.

I ended up finding a way to use Lodash's _.remove function to remove matching array strings as follows:

 // The String (SubString) we want to match against array (for dropping purposes)
 var searchSubString = "whatever" 
 // Remove all array items that contain the text "whatever"
 _.remove(my_array, function(searchSubString) {
 return n.indexOf(searchSubString) !== -1;
 });

Basically indexOf is matching against the position of the substring within the string, if the substring is not found it will return -1, when indexOf returns a number other than -1 (the number is the SubString position in number of characters within the Array string).

Lodash removes that Array item via array mutation and the newly modified array can be accessed by the same name.

answered Jan 25, 2018 at 16:59

Comments

-1
_.some(myArray, function(str){
 return _.includes(str, 'orange')
})
answered Feb 25, 2016 at 17:59

Comments

-1
let str1 = 'la rivière et le lapin sont dans le près';
let str2 = 'product of cooking class';
let str3 = 'another sentence to /^[analyse]/i with weird!$" chars@';
_.some(_.map(['rabbit','champs'], w => str1.includes(w)), Boolean), // false
_.some(_.map(['cook'], w => str2.includes(w)), Boolean), // true
_.some(_.map(['analyse'], w => str3.includes(w)), Boolean), // true
answered May 11, 2017 at 9:40

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.