list

Split a List in pieces

How would you SPLIT a List in pieces of specified length ? …. Here is how :

:- initialization(main).

say(L) :- write(L), write('\n').

%%this illustrates how to pick part of a List
firstN(Lst,N,FirstN) :- length(FirstN,N), append(FirstN,_Rest,Lst).

split([],_,[]) :- !.
split(Lst, N, [FirstN|Res]) :- 
   length(FirstN, N), append(FirstN, Rest, Lst), !, split(Rest, N, Res).
%%when the last piece is smaller than the requested size
split(Lst, N, [Lst]) :- length(Lst, Len), Len < N.

main :- 
L = [1,2,3,4,5,6], say(L),
firstN(L,5,F), say(F),
split(L,2,L2), say(L2),
split(L,3,L3), say(L3),
split(L,4,L4), say(L4).

----

[1,2,3,4,5,6]
[1,2,3,4,5]
[[1,2],[3,4],[5,6]]
[[1,2,3],[4,5,6]]
[[1,2,3,4],[5,6]]

HashList for key:value pairs

In Prolog if you need to use hashes you can use Dicts, but for small number of kv-pairs it is overkill.

In such cases use the HashList that I invented ;). It is very easy and you can use it as a Two way hash too. Very handy.

% HashList utils : [ key1:val1, key2:val2, ... ], also can be used as TwoWaysHash
keys(HL,Res) :- maplist(\I^K^(I = K:_),HL,Res).
vals(HL,Res) :- maplist(\I^V^(I = _:V),HL,Res).
val(Key,HL,Res) :- member(Key:Res,HL).
key(Val,HL,Res) :- member(Res:Val,HL).

-----

?- use_module(library(lambda)).

?- H = [first:john, last:doe, city:huston, state:tx],
keys(H,Keys),vals(H,Vals),
val(city,H,Val),key(huston,H,Key).

H = [first:john, last:doe, city:huston, state:tx],
Keys = [first, last, city, state],
Vals = [john, doe, huston, tx],
Val = huston,
Key = city .

List to Map

Here is and easy way to convert List to a Map where the index is used as key :

import java.util.*;

public class Test {
  
 public static <ARG> void say(ARG arg) { System.out.println(arg); }

 public static HashMap<Integer, ?> list2map(List lst) {
    HashMap map = new HashMap();
	for (int i=0; i < lst.size(); i++) {
		map.put(i, lst.get(i));
	}
	return map;
  }

  public static void main(String[] args) {
      List a = Arrays.asList( 1,2,3,4 );
      say(a);
      say(list2map(a));
  }
}

Output:

[1, 2, 3, 4]
{0=1, 1=2, 2=3, 3=4}

You can directly test it (the code already setup for you) here in OneCompiler editor : https://onecompiler.com/java/3xh55parb

Flatten List of Lists

Python do not have in the List library function to flatten a LoL, but don’t despair here are two possible ways.
The first trick works only for pure 2 level list, as you can see :

: sum([[1],[2,3]],[])                                                                                                                                                 
[1, 2, 3]

: sum([[1],[2,3,[4,5]]],[])                                                                                                                                           
[1, 2, 3, [4, 5]]

: sum([1,[2,3]],[])                                                                                                                                                   
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-23-d56eb05286e1> in <module>
----> 1 sum([1,[2,3]],[])

TypeError: can only concatenate list (not "int") to list

the second one guard against “dismantling” a string :

def flatten(LoL):
	for el in LoL:
		if isinstance(el, collections.Iterable) and not isinstance(el, str):
			for sub in flatten(el): yield sub
		else: yield el

: list(flatten2([1,[2,3,[4,5],'abc',(6,7,'cde')]]))                                                                                                                   
: [1, 2, 3, 4, 5, 'abc', 6, 7, 'cde']

List-in-List membership

Prolog has a predicate member, which checks if an item is in a list, but what if you want to know if multiple elements are part of a list.

%is elems from Lst1 also elems of Lst2
members(Lst1,Lst2) :- maplist( \X^(member(X,Lst2)), Lst1).

example use, but as you see it needs the lambda module :

?- use_module(library(lambda)).
?- members([3,4],[1,2,3,4]).
true .

?- members([3,4,5],[1,2,3,4]).
false.

Just found out you can get similar results with subset, but

The library(lists) contains a number of old predicates for manipulating sets represented as unordered lists, notably intersection/3union/3subset/2 and subtract/3. These predicates all use memberchk/2 to find equivalent elements. As a result these are not logical while unification can easily lead to dubious results.
…..
deprecated: New code should use library(ordsets) instead.