Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide version of AbstractStreamEx#indexOf which returns int #161

Open
chashnikov opened this issue Oct 5, 2017 · 3 comments
Open

Provide version of AbstractStreamEx#indexOf which returns int #161

chashnikov opened this issue Oct 5, 2017 · 3 comments

Comments

@chashnikov
Copy link

It's inconvenient to cast result of indexOf from long to int. I think developers usually work with streams which contains less than 2^31 elements. So it would be great to have a variant of this method which returns OptionalInt or even int as List::indexOf does.

@amaembo
Copy link
Owner

amaembo commented Nov 11, 2017

Please show a complete use-case where you want to use such method. Note that as indexOf name is already taken, new one would be longer like integralIndexOf or indexOfInt. In this case it will be not much shorter than adding an explicit narrowing conversion like (int). Currently I think that adding such method would make API more bloating and confusing. If you like a fluent style and adding (int) on the left looks bad for you, an existing option is to create an utility method in your project like this:

static <T> Function<StreamEx<T>, Integer> indexOf(T t) {
  return s -> (int)(s.indexOf(t).orElse(-1));
}

And use it like this:

int idx = streamEx.chain(indexOf("foo"));

@chashnikov
Copy link
Author

See my changes in AbstractProjectNode. I need to cast the result to int in order to pass it to subList. In fact all usages of indexOf in IDEA sources cast the result to int.

You're right, it's indeed not that simple to invent a name for this new method. I don't think it's number of characters that matters, it's better to have readable and comprehensible code even if it's (slightly) longer. And I think that something like stream.intIndexOf(value) is more readable than (int) stream.indexOf(value).orElse(-1)).

If we decide that the current version is not convenient and deprecate it, we can use a simpler name for the new method, there will be no need to mention int in it (e.g. firstIndexOf). But maybe it's too much.

@amaembo
Copy link
Owner

amaembo commented Nov 24, 2017

You actually don't need an index, you need a prefix. How about this?

commonGroupsPath = StreamEx.of(commonGroupsPath).zipWith(path.stream())
            .takeWhile(e -> e.getKey().equals(e.getValue())).keys().toList();

(Unlike zip the zipWith method stops as soon as one of the streams finishes, as you cannot know the stream length in advance. In particular it's possible to zip infinite stream with finite one to get a finite result).
Well, it will make a new copy instead of subList, but probably it's not a big problem for this code.

In general indices are rarely necessary. Sometimes they are just used as crutches because API does not allow you to get the result without them, but the final result does not include indices.

Btw I have commonPrefix and commonSuffix collectors, but they work for strings only. Probably I should add similar collectors for lists. In this case it would be possible to write (assuming that getGroupPath is not very complex and can be executed several times):

ModuleGrouper grouper = ModuleGrouper.instanceFor(myProject);
Set<ModuleDescription> nonGroupedModules = StreamEx.of(modules)
      .filter(md -> grouper.getGroupPath(md).isEmpty()).toCollection(LinkedHashSet::new);
Set<String> topLevelGroups = StreamEx.of(modules).map(grouper::getGroupPath)
      .remove(List::isEmpty).map(path -> path.get(0)).toCollection(LinkedHashSet::new);
List<String> commonGroupsPath = StreamEx.of(modules).map(grouper::getGroupPath)
    .collect(MoreCollectors.commonListPrefix());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants