Flattens the nested array - if-statement

function steamrollArray(arr) {
let newArr = [];
arr.forEach(el => {
if(Array.isArray(el)) {
newArr.push(...steamrollArray(el));
}
newArr.push(el);
})
return newArr;
}
steamrollArray([1, [2], [3, [[4]]]]);
It is supposed to log the output [1, 2, 3, 4].
My question is why I have to put "else" after if-statement to make it work in the above code.
I do not know why else makes some difference.
Could you help me?

Well, without the else you would always append the original element to the result list, even a previously "steamrolled" sub-list. With the else, the original element is only added to the result list if it is not a list itself.
I did not test it, but I think without the else the result would thus be something like [1, 2, [2], 3, 4, [4], [[4]], [3, [[4]]]]

Related

How can i sort a list from specifik criteria

I have this list and I want to sort the list. This is just a smaller example of what I want to do, but I get the same error. I dont understand why I can't make this work.
I have tried using google to solve the problem but without luck.
lst = [3, 4, 5, 6]
if lst < 4:
lst.pop()
print(lst)
How can i do this it shows
TypeError:'<' not supported between instances of 'list' and 'in
I think that your goal is to remove all elements in the list that are lesser than 4. You can use this simple list comprehension in order to achieve what you want:
lst = [3, 4, 5, 6]
lst = [elem for elem in lst if elem >= 4]
print(lst)
Output:
[4, 5, 6]

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.

Elixir: clone a list idiomatically

I can always do something like this:
new_list = Enum.map(old_list, fn x -> x end)
There is a dozen more equally, or marginally less ugly, ways of doing so, of course. Somehow, I can't find an idiomatic way of copying a list. There certainly must be a way.
Elixir is an immutable language, so the idiomatic way is this:
clone = original
There is no need to "clone". The data assigned to existing variables cannot be edited, so assigning one variable to another conceptually results in a copy of the data. You cannot edit existing data - if you reassign to an existing variable, you are conceptually pointing that variable at a new data-structure.
original = [1, 2, 3] |> IO.inspect(label: "original")
clone = original |> IO.inspect(label: "clone")
prepended = [0 | original] |> IO.inspect(label: "prepended")
original |> IO.inspect(label: "original again")
original = [5, 6, 7] |> IO.inspect(label: "original rebound")
clone |> IO.inspect(label: "clone again")
Output:
original: [1, 2, 3]
clone: [1, 2, 3]
prepended: [0, 1, 2, 3]
original again: [1, 2, 3]
original rebound: [5, 6, 7]
clone again: [1, 2, 3]
Since data structures in Elixir are immutable, I can't think of a reason you'd ever need to "clone" a list. It would do nothing. That being said, if you're looking for a way to do that exact nothing, you could reach for Enum.to_list/1.
iex> Enum.to_list([1, 2, 3])
[1, 2, 3]

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.

How to flatten a nested list in Vim script?

I found some Vim list functions can not work as I thought.
For example:
let list0 = [1, [1, 2]]
echo count(list0, 1)
It returns 1, but I want it returns 2. So I think those functions can not deep into nested lists, only work on first level.
I think here I should expand nested list into a normal list like this:
list0 = [1, 1, 2]
How to flatten a nested list?
" Code from bairui##vim.freenode
" https://gist.github.com/3322468
function! Flatten(list)
let val = []
for elem in a:list
if type(elem) == type([])
call extend(val, Flatten(elem))
else
call add(val, elem)
endif
unlet elem
endfor
return val
endfunction
Here unlet elem is necessary. Because the elem variable is changing, it is a list item, or a list, and VimL does not support assign a list item to a list, and vice versa.
You can use reduce() since 8.2.0878:
let mylist = [[1, 2], [3, 4], 5]
echo reduce(mylist, { acc, val -> type(val) == 3 ? extend(acc, val) : add(acc, val)})
outputs:
[1, 2, 3, 4, 5]
I suggest vital.vim's Data.List.flatten as an another answer ;D
https://github.com/vim-jp/vital.vim