Delete repeated data with Set in a nested list (Dart) - list

I have problems removing repeated data from a nested list, I need to remove the records that are not repeated in the index 0 of the list, but the Set method is not doing anything when the list is nested.
for (int i = 0; i < items.length; i++) {
sections.add([items[i].sectionG, items[i].logo]);
}
sections = sections.toSet().toList();
Imagen de la estructura de la lista
When I go through Set I get back the same structure as before.

operator == for most Dart objects, including Lists, Sets, and Maps, checks only for object identity and does not perform deep equality checks. That is, two separate List objects do not compare equal even if they contain the same elements.
You will need to create a Set that performs deep equality checks. package:collection provides an EqualitySet class that can use a ListEquality object to compare List elements:
import 'package:collection/collection.dart';
void main() {
var listOfLists = [
[1, 2, 3],
[1, 2],
[1, 2, 3, 4],
[1, 2, 3],
];
var set = EqualitySet.from(ListEquality<int>(), listOfLists);
print(set); // Prints: {[1, 2, 3], [1, 2], [1, 2, 3, 4]}
}

Related

Is there anything to perform union of two lists in Erlang?

I found out that there are set operations for sets in Erlang, but I could not find out similar operations for lists. I want to perform the basic union operation in lists in Erlang:
A = [1, 2, 3]
B = [1, 2, 5]
C = A union B = [1, 2, 3, 5]
How can I perform this operation in Erlang?
I did the following using sets, though, and it works. I was just wondering, if I can do this without sets.
C = sets:to_list(sets:union(sets:from_list(A),sets:from_list(B))).
You can concatenate the two lists and then sort them, removing duplicates:
A = [1, 2, 3],
B = [1, 2, 5],
C = lists:usort(A ++ B).
The ordsets module handles ordered lists as sets, using the same API as the sets module. https://erlang.org/doc/man/ordsets.html

What is the use of returning [...list] in Dart?

In Dart programming language, sometimes I see functions returning a list in pair of brackets with triple dots [...list]. For example:
class IntList {
List<int> _integerList = [1, 2, 3, 4, 5];
List<int> get integerList {
return [..._integerList];
}
}
So what is the difference between return integerList; and the above return statement?
Any help is really appreciated. Thank you.
For this particular case there is no difference. ... is the spread operator. This allows you to insert multiple elements into a collection.
For example:
var list = [1, 2, 3];
var list2 = [0, ...list];
print(list2)
Output:
[0, 1, 2, 3]
So doing return [..._integerList]; is the exact same as return integerList;, other than that it creates a new list.
var list = [1, 2, 3];
print(list.hashCode);
print([...list].hashCode);
This code shows that they are different List objects when the spread operator is used because of the output of different hash codes.

Is there a Dart utility for converting a flat list into a nested one?

It's a common problem here, but I couldn't find any simplified methods for Dart in particular - how can I convert a list like this
[1, 2, 3, 4, 5, 6]
into a list like this
[[1, 2], [3,4], [5,6]]
assuming there are no extra elements after this?
Dart Quiver package is a set of utility libraries for Dart that makes using many Dart libraries easier and more convenient or adds additional functionality (https://github.com/google/quiver-dart).
You can use the partition function from quiver iterables library as follows.
import 'package:quiver/iterables.dart';
main() {
var list = [1, 2, 3, 4, 5, 6];
# Use partition function to segment lists into chunks of size 2
var newList = partition<int>(list, 2);
print (newList);
}
Result [[1, 2], [3,4], [5,6]]
var list = [1, 2, 3, 4];
List<int> temp = [];
List<List<int>> newList = list.fold<List<List<int>>>([], (newList, i) {
if (temp.length < 2) {
temp.add(i);
}
if (temp.length >= 2) {
List<int> newValue = new List<int>.from(temp);
newList.add(newValue);
temp.clear();
}
return newList;
});
print(newList);

python 2-D array get the function as np.unique or union1d

as follows I have a 2-D list/array
list1 = [[1,2],[3,4]]
list2 = [[3,4],[5,6]]
how can I use the function as union1d(x,y)to make list1 and list2 as one list
list3 = [[1,2],[3,4],[5,6]]
union1d just does:
unique(np.concatenate((ar1, ar2)))
so if you have a method of finding unique rows, you have the solution.
As described in the suggested link, and elsewhere, you can do this by converting the array to a 1d structured array. Here the simple version is
If arr is:
arr=np.array([[1,2],[3,4],[3,4],[5,6]])
the structured equivalent (a view, same data):
In [4]: arr.view('i,i')
Out[4]:
array([[(1, 2)],
[(3, 4)],
[(3, 4)],
[(5, 6)]],
dtype=[('f0', '<i4'), ('f1', '<i4')])
In [5]: np.unique(arr.view('i,i'))
Out[5]:
array([(1, 2), (3, 4), (5, 6)],
dtype=[('f0', '<i4'), ('f1', '<i4')])
and back to 2d int:
In [7]: np.unique(arr.view('i,i')).view('2int')
Out[7]:
array([[1, 2],
[3, 4],
[5, 6]])
This solution does require a certain familiarity with compound dtypes.
Using return_index saves that return view. We can index arr directly with that index:
In [54]: idx=np.unique(arr.view('i,i'),return_index=True)[1]
In [55]: arr[idx,:]
Out[55]:
array([[1, 2],
[3, 4],
[5, 6]])
For what it's worth, unique does a sort and then uses a mask approach to remove adjacent duplicates.
It's the sort that requires a 1d array, the rest works in 2d
Here arr is already sorted
In [42]: flag=np.concatenate([[True],(arr[1:,:]!=arr[:-1,:]).all(axis=1)])
In [43]: flag
Out[43]: array([ True, True, False, True], dtype=bool)
In [44]: arr[flag,:]
Out[44]:
array([[1, 2],
[3, 4],
[5, 6]])
https://stackoverflow.com/a/16971324/901925 shows this working with lexsort.
================
The mention of np.union1d set me and Divakar to focus on numpy methods. But it starting with lists (of lists), it is likely to be faster to use Python set methods.
For example, using list and set comprehensions:
In [99]: [list(x) for x in {tuple(x) for x in list1+list2}]
Out[99]: [[1, 2], [3, 4], [5, 6]]
You could also take the set for each list, and do a set union.
The tuple conversion is needed because a list isn't hashable.
One approach would be to stack those two input arrays vertically with np.vstack and then finding the unique rows in it. It would be memory intensive as we would discard rows from it thereafter.
Another approach would be to find the rows in the first array that are exclusive to it, i.e. not present in the second array and thus just stacking those exclusive rows alongwith the second array. Of course, this would assume that there are unique rows among each input array.
The crux of such a proposed memory-saving implementation would be to get those exclusive rows from first array. For the same we would convert each row into a linear index equivalent considering each row as an indexing tuple on a n-dimensional grid, with the n being the number of columns in the input arrays. Thus, assuming the input arrays as arr1 and arr2, we would have an implementation like so -
# Get dim of ndim-grid on which linear index equivalents are to be mapped
dims = np.maximum(arr1.max(0),arr2.max(0)) + 1
# Get linear index equivalents for arr1, arr2
idx1 = np.ravel_multi_index(arr1.T,dims)
idx2 = np.ravel_multi_index(arr2.T,dims)
# Finally get the exclusive rows and stack with arr2 for desired o/p
out = np.vstack((arr1[~np.in1d(idx1,idx2)],arr2))
Sample run -
In [93]: arr1
Out[93]:
array([[1, 2],
[3, 4],
[5, 3]])
In [94]: arr2
Out[94]:
array([[3, 4],
[5, 6]])
In [95]: out
Out[95]:
array([[1, 2],
[5, 3],
[3, 4],
[5, 6]])
For more info on setting up those linear index equivalents, please refer to this post.

To check if sublist exists in another list

coll = [[3, 3], [2, 2, 2], [2, 4], [2, 3], [2, 2]]
main = [4, 3, 3, 2, 2, 2, 2, 2, 2, 2]
I have 2 lists. 'coll' is a list of lists with each sublist containing integers which might have duplicates(ex- [2, 2, 2]). And main is a list containing integers. I want to check if the sublist elements of 'coll' are present in 'main' or not. For this case, it is true since [2, 2, 2], [3, 3] and other sublists are present. The order of elements in the sublist and 'main' doesn't matter. Whatever elements are present in sublist they may be present in 'main' in any position.
I cannot use sets because of the presence of duplicates. And also I cannot use strings because:
coll = ['222']
main = ['423262']
I have used a sample of sublist to show the problem with using string. My algorithm requirement is that in this case also 'true' is returned because '2' is present at 3 locations , index- 1, 2, 5. But:
if coll in main:
return True
else:
return False
this returns false if I use strings for checking.
Please suggest any method.
I think the most readable way to do that is to create a Counter instance for each of your sublists, and them check with the list "count" method if it matches the requirement for each argument of the sublist:
from itertools import Counter
def checksub(main, sublist):
c = Counter(sublist)
for num, count in c.items():
if main.count(num) < count:
return False
return True
all(checksub(main, sublist) for sublist in coll)
This is not fast - if you are iterating over a large data volume, you'd better use some approach that map the "main" list into a data-structure where the counting can be checked in a faster way tahn using "count". Or, if there are few distinct numbers, even something as simple as cache the returns of "count" for each different number.
Otherwise for small sizes of "main" this might suffice.
On a second reading of your question, it seems like you only require that one of the sublists be present in main - if that is the case, just replace the call to all for any above.