0

Is there a way, ideally using higher order functions, to filter out the repeating substring elements in an array? For example:

var obj = ["a", "a.b.c", "a.b", "a.e", "a.b.d"]

to become

["a.b.c", "a.e", "a.b.d"] //since both "a" and "a.b" appear inside either "a.b.c" or "a.b.d".

The solution will probably require Hashtables or Sets but I am not sure how to get started.

2
  • So you are wanting the longest repeat of a substring, not the first, correct? Hence why you favored "a.b.c" over "a.b" or "a", yes? Commented Jul 18, 2018 at 19:26
  • @mhodges Yes, because "a.b.c" contains "a.b" AND "a" in it already Commented Jul 18, 2018 at 19:45

3 Answers 3

3

Can use a filter() and find() combination along with a Set to remove duplicates

var data = ["a", "a.b.c", "a.b", "a.e", "a.b.d"];

var res = [...new Set(data)].filter(val => !data.find(s => s !== val && s.startsWith(val)));

console.log(res)

Sign up to request clarification or add additional context in comments.

Comments

2

You could use the array .reduce function to do this.

Just see if your current string is a substring of something already in the array, and ignore it if so. Otherwise, if something in the array is a substring of the current string, replace it. And finally, if neither is the case, add the current string to the array:

var obj = ["a", "a.b.c", "a.b", "a.e", "a.b.d"]

var result = obj.reduce((deduped, item) => {
  if (deduped.some(s => s.includes(item))) return deduped;
  
  const replace = deduped.findIndex(s => item.includes(s));
  if (replace !== -1) {
    deduped.splice(replace, 1, item)
  } else {
    deduped.push(item)
  }
  
  return deduped;
}, []);

console.log(result)

Comments

2

An alternative is using the function filter to get the desired elements, the function some to check at least one match and the function includes to check if the current element is a substring.

This approach finds a substring to identify a match.

var obj = ["a", "a.b.c", "a.b", "a.e", "a.b.d"],
    filtered = obj.filter((element, i, arr) => !arr.some((o, oi) => {
      return oi === i ? false : o.includes(element);
    }));

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

Comments

Your Answer

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.