@@ -1343,7 +1343,9 @@ class _DuplicateItemRecordList {
1343
1343
record._prevDup = null ;
1344
1344
} else {
1345
1345
// adding a duplicate [ItemRecord] to the list
1346
- assert (record.item == _head.item);
1346
+ assert (identical (record.item, _head.item) ||
1347
+ record.item is String && _head.item is String && record.item == _head.item ||
1348
+ record.item is num && record.item.isNaN && _head.item is num && _head.item.isNan);
1347
1349
if (insertBefore == null ) {
1348
1350
_tail._nextDup = record;
1349
1351
record._prevDup = _tail;
@@ -1369,9 +1371,12 @@ class _DuplicateItemRecordList {
1369
1371
ItemRecord get (item, int afterIndex) {
1370
1372
ItemRecord record;
1371
1373
for (record = _head; record != null ; record = record._nextDup) {
1372
- if ((afterIndex == null || afterIndex < record.currentIndex) &&
1373
- identical (record.item, item)) {
1374
- return record;
1374
+ if (afterIndex == null || afterIndex < record.currentIndex) {
1375
+ if (identical (record.item, item) ||
1376
+ record.item is String && item is String && record.item == item ||
1377
+ record.item is num && record.item.isNaN && item is num && item.isNan) {
1378
+ return record;
1379
+ }
1375
1380
}
1376
1381
}
1377
1382
return null ;
@@ -1414,10 +1419,12 @@ class _DuplicateItemRecordList {
1414
1419
* The list of duplicates is implemented by [_DuplicateItemRecordList] .
1415
1420
*/
1416
1421
class DuplicateMap {
1422
+ static final nanKey = const Object ();
1417
1423
final map = new HashMap <dynamic , _DuplicateItemRecordList >();
1418
1424
1419
1425
void put (ItemRecord record, [ItemRecord insertBefore = null ]) {
1420
- map.putIfAbsent (record.item, () => new _DuplicateItemRecordList ()).add (record, insertBefore);
1426
+ var key = _getKey (record.item);
1427
+ map.putIfAbsent (key, () => new _DuplicateItemRecordList ()).add (record, insertBefore);
1421
1428
}
1422
1429
1423
1430
/**
@@ -1427,9 +1434,10 @@ class DuplicateMap {
1427
1434
* Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
1428
1435
* have any more `a` s needs to return the last `a` not the first or second.
1429
1436
*/
1430
- ItemRecord get (key, [int afterIndex]) {
1437
+ ItemRecord get (value, [int afterIndex]) {
1438
+ var key = _getKey (value);
1431
1439
_DuplicateItemRecordList recordList = map[key];
1432
- return recordList == null ? null : recordList.get (key , afterIndex);
1440
+ return recordList == null ? null : recordList.get (value , afterIndex);
1433
1441
}
1434
1442
1435
1443
/**
@@ -1438,10 +1446,11 @@ class DuplicateMap {
1438
1446
* The list of duplicates also is removed from the map if it gets empty.
1439
1447
*/
1440
1448
ItemRecord remove (ItemRecord record) {
1441
- assert (map.containsKey (record.item));
1442
- _DuplicateItemRecordList recordList = map[record.item];
1449
+ var key = _getKey (record.item);
1450
+ assert (map.containsKey (key));
1451
+ _DuplicateItemRecordList recordList = map[key];
1443
1452
// Remove the list of duplicates when it gets empty
1444
- if (recordList.remove (record)) map.remove (record.item );
1453
+ if (recordList.remove (record)) map.remove (key );
1445
1454
return record;
1446
1455
}
1447
1456
@@ -1451,5 +1460,8 @@ class DuplicateMap {
1451
1460
map.clear ();
1452
1461
}
1453
1462
1463
+ /// Required to handle num.NAN as a Map value
1464
+ dynamic _getKey (value) => value is num && value.isNaN ? nanKey : value;
1465
+
1454
1466
String toString () => "DuplicateMap($map )" ;
1455
1467
}
0 commit comments