比较两个不等长的列表并删除部分匹配?

时间:2017-02-14 12:58:39

标签: java list

假设我有两个列表,如:

List1 = Fulton Tax Commissioner 's Office, Grady Hospital, Fulton Health Department

List2 = Atlanta Police Department, Fulton Tax Commissioner, Fulton Health Department,Grady Hospital

我希望我的最终列表看起来像这样:

Final List = Fulton Tax Commissioner 's Office,Grady Hospital,Fulton Health Department,Atlanta Police Department

我可以通过将两个列表添加到集合中来删除这些列表中的重复项。但是,如何删除像富尔顿税务专员那样的部分匹配?

2 个答案:

答案 0 :(得分:1)

通过传递比较器来添加到设置,如下所示:

// Basic example
import { clone } from 'lodash';

interface IState {
  foo: string;
}

const state: Readonly<IState> = {
  foo: "bar"
};

// Start situation
function modifyState<S>(
  prevState: S,
  updateFunc: (update: S) => void
): S {
  const newState = clone(prevState);
  updateFunc(newState);
  return newState;
}

modifyState(
  state,
  update => {
    update.foo = "another string"; // 'Cannot assign to 'foo' because it is a constant or a read-only property.'
  }
);

答案 1 :(得分:1)

我建议:将结果设置为列表1的副本。对于列表2的每个成员:

  • 如果结果包含相同的成员,请跳过它。
  • 如果结果包含以列表2成员开头的成员,也请跳过列表2成员
  • 如果结果包含作为列表2成员前缀的成员,请将其替换为列表2成员
  • 否则将列表2成员添加到结果中。

如果使用Java 8,可以使用流来方便地完成第2和第3个项目符号中的测试,例如result.stream().anyMatch(s -> s.startsWith(list2Member));

还有优化空间,例如使用TreeSet(如果可以对项目进行排序)。

编辑:在Java中:

    List<String> result = new ArrayList<>(list1);
    for (String list2Member : list2) {
        if (result.stream().anyMatch(s -> s.startsWith(list2Member))) { // includes case where list2Member is in result
            // skip
        } else {
            OptionalInt resultIndex = IntStream.range(0, result.size())
                    .filter(ix -> list2Member.startsWith(result.get(ix)))
                    .findAny();
            if (resultIndex.isPresent()) {
                result.set(resultIndex.getAsInt(), list2Member);
            } else {
                result.add(list2Member);
            }
        }
    }

结果是:

[Fulton Tax Commissioner 's Office, Grady Hospital, Fulton Health Department, Atlanta Police Department]

我相信这正是你要求的结果。

进一步编辑:在Java 9中,您可以使用(未​​经测试):

            resultIndex.ifPresentOrElse(ix -> result.set(ix, list2Member), () -> result.add(list2Member));