Skip to content

Commit e703e19

Browse files
Preserve order in ArrayUnion (#8050)
1 parent 330ed4a commit e703e19

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

Firestore/core/src/model/transform_operation.cc

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include <functional>
2020
#include <memory>
2121
#include <ostream>
22-
#include <set>
2322
#include <utility>
2423

2524
#include "Firestore/core/include/firebase/firestore/timestamp.h"
@@ -38,13 +37,6 @@ namespace model {
3837

3938
using Type = TransformOperation::Type;
4039

41-
struct ValueCompare {
42-
bool operator()(const google_firestore_v1_Value& lhs,
43-
const google_firestore_v1_Value& rhs) const {
44-
return Compare(lhs, rhs) == util::ComparisonResult::Ascending;
45-
}
46-
};
47-
4840
// MARK: - TransformOperation
4941

5042
TransformOperation::TransformOperation(std::shared_ptr<const Rep> rep)
@@ -254,10 +246,15 @@ google_firestore_v1_Value ArrayTransform::Rep::Apply(
254246
CoercedFieldValueArray(previous_value);
255247
if (type_ == Type::ArrayUnion) {
256248
// Gather the list of elements that have to be added.
257-
std::set<google_firestore_v1_Value, ValueCompare> new_elements;
249+
std::vector<google_firestore_v1_Value> new_elements;
258250
for (pb_size_t i = 0; i < elements_->values_count; ++i) {
259-
if (!Contains(array_value, elements_->values[i])) {
260-
new_elements.insert(elements_->values[i]);
251+
const google_firestore_v1_Value& new_element = elements_->values[i];
252+
if (!Contains(array_value, new_element) &&
253+
!std::any_of(new_elements.begin(), new_elements.end(),
254+
[&](const google_firestore_v1_Value& value) {
255+
return value == new_element;
256+
})) {
257+
new_elements.push_back(new_element);
261258
}
262259
}
263260

Firestore/core/test/unit/model/mutation_test.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,15 @@ TEST(MutationTest,
344344
TransformBaseDoc(base_data, transforms, expected);
345345
}
346346

347+
TEST(MutationTest,
348+
AppliesLocalArrayUnionTransformWithExistingElementsInOrder) {
349+
// New elements should be appended in order.
350+
auto base_data = Map("array", Array(1, 3));
351+
TransformPairs transforms = {{"array", ArrayUnion(1, 2, 3, 4, 5)}};
352+
auto expected = Map("array", Array(1, 3, 2, 4, 5));
353+
TransformBaseDoc(base_data, transforms, expected);
354+
}
355+
347356
TEST(MutationTest, AppliesLocalArrayUnionTransformWithDuplicateUnionElements) {
348357
// Duplicate entries in your union array should only be added once.
349358
auto base_data = Map("array", Array(1, 3));

0 commit comments

Comments
 (0)