TransWikia.com

Is it possible to map a list with 'set' method for getting directly a list, instead a matrix, avoiding for-loop use?

Geographic Information Systems Asked by xunilk on April 3, 2021

The use of for-loops is discouraged in Google Earth Engine because there is pointed out that the same results can be achieved using a map() operation with a specific function independently applied to each element. In following code, I have an initial list of zero values where I want to introduce ones in positions established by a list of indices of non nulls values (idxList). I spent a lot of time trying to find out a map operation for producing that list but, instead a list, it produces a matrix with values placed in adequate positions but it requires additional processing for getting a single list. However, the "discouraged" for-loop produces my desired solution by using directly ‘set’ method. Functional code looks as follows:

var option = ee.List.repeat(0, 8);

print("initial list", option);

var option2 = option;

var idxList = ee.List([1, 3, 4, 5, 6 ]);

print("index non nulls values", idxList);

var n = idxList.size().getInfo();

for (var i = 0; i < n; i += 1) {
  
  option = option.set(idxList.get(i), 1);
  
}

print("desired solution but with for loop", option);

var new_list = ee.List([0, 1, 2, 3, 4]);

var int_lists = new_list.map(function setting (ele){
  
  return option2.set(idxList.get(ele), 1);
  
});

print("result mapping a list", int_lists);

Is it possible to map a list with ‘set’ method (or using its ‘iterate’ method) for getting directly a desired result list, instead a matrix, avoiding for-loop use?

One Answer

I found out two possible solutions condensed in following code. The first one uses as input the matrix (list of lists) obtained by mapping idxList (too many lines of code compared to for-loop solution). The second one is shorter and uses 'matrixTranspose' method from ee.Array objects for simplifying the process. However, I'm also looking for a solution by using 'iterate' method of ee.List objects in GEE. I cannot find an example yet. I will accept this option as valid answer to this question.

var option = ee.List.repeat(0, 8);

print("initial list", option);

var option2 = option;

var idxList = ee.List([1, 3, 4, 5, 6 ]);

print("index non nulls values", idxList);

var n = idxList.size().getInfo();

for (var i = 0; i < n; i += 1) {
  
  option = option.set(idxList.get(i), 1);
  
}

print("desired solution but with for loop", option);

var new_list = ee.List([0, 1, 2, 3, 4]);

var int_lists = new_list.map(function (ele){
  
  return option2.set(idxList.get(ele), 1);
  
});

print("result mapping a list", int_lists);

var list2 = ee.List([0, 1, 2, 3, 4, 5, 6, 7]);

var option2 = list2.map(function(e) {

  var col = int_lists.map(function(ele) {
  
    return ee.List(ele).get(e);
  
  });

  return ee.List(col).reduce(ee.Reducer.sum());

});

print("desired solution mapping a list of lists", option2);

var option3 = ee.Array(int_lists).matrixTranspose().toList().map(function (ele){
  
  return ee.List(ele).reduce(ee.Reducer.sum());
  
});

print("desired solution by using an array", option3);

Editing Note:

I found out an example of use of 'iterate' method in this answer with an Image Collection. I adapted it with ee.List objects as follows:

var idxList = ee.List([1, 3, 4, 5, 6 ]);

var option4 = ee.List.repeat(0, 8);

var first = option4;

var appendValues = function(iter, previous) {
  
  return ee.List(previous).set(iter, 1);

};
  
print(idxList.iterate(appendValues, first));

It works as expected!.

Correct answer by xunilk on April 3, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP