1

I am trying to write a for loop to append elements dynamically to an array. However, the dimensions of the array change on every loop run, throwing off error.

var arr = 1
for (var i=0;i<4;++i){
  var newval = somefunction()
  arr = ee.Array.cat([newvar,arr],0)
}
print(arr)

Error: Array.cat: Arrays must have same dimensionality. Expected 0, found 1 for array 1.

EDIT: The new value to be appended is coming out of a for loop, so I can't use a list.map or iterate function

5

Your code is returning "unexpected" results because you are mixing client-side Javascript control structures with server-side Earth Engine methods. In general, you should avoid doing this. Review the Earth Engine Client vs. Server docs page for a complete discussion.

For your simple example, you can use an ee.List() object to accumulate values, and later convert it to an ee.Array():

var first = ee.List([1]);

var list = ee.List.sequence(0, 4);
var iter_function = function (num, list){
  num = ee.Number(num);
  var new_value = num.multiply(num);
  return ee.List(list).add(new_value);
};

var resulting_list = list.iterate(iter_function, first);
print('resulting_list', resulting_list);

var resulting_array = ee.Array(resulting_list);
print('resulting_array', resulting_array);

However, if your actual use case is too complex for ee.List() objects, you can iterate using ee.Array() objects:

var first = ee.Array([1]);

var list = ee.List.sequence(0, 4);
var iter_function = function (num, list){
  num = ee.Number(num);
  var new_value = ee.Array([num.multiply(num)]);
  return ee.Array.cat([list, new_value]);
};

var resulting_array = list.iterate(iter_function, first);
print('resulting_array', resulting_array);

If processing each element in your list is independent of the others, you can map your function across this list using ee.List.map() instead:

var list = ee.List.sequence(0, 4);
var map_function = function (num){
  num = ee.Number(num);
  var new_value = num.multiply(num);
  return new_value;
};

var resulting_list = list.map(map_function);
print('resulting_list', resulting_list);

var resulting_array = ee.Array(resulting_list);
print('resulting_array', resulting_array);

The moral of this story is: "Friends don't let friends use loops with big data."

  • Thanks for explaining it well. But my case really needs to use a for loop, as the num variable is coming from a for loop. Is it possible somehow? I have made edits in the question to show this. – shahryar Feb 5 '18 at 2:21
0

Although Tyler has given a very comprehensive and well-explained answer using the server-side code which is recommended to use, but in cases like mine where it is necessary to use the for loop, here is the solution I figured out:

var list = ee.List.sequence(0,1);
for (var i=2;i<6;++i){
  var new_value = ee.Number(i).multiply(ee.Number(i)); //can come from some function
  list = list.add(new_value)
}
print(list)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.