How to return a selected element from an array using map ()? - node.js

I have a problem with mapping. I want to return an element from two arrays. Both arrays have a similar structure ['0', {args: (3) ......}] I would like to return the "args" element from both. "bscArray" has args [2] the same as polygonArray args [0]. So I would like to map them to new arrays first and then merge them into one. Unfortunately, the terminal still returns "undefined" to me, and in the debugger they are not even visible. How to fix it?
let jsonValueBsc = JSON.parse(fs.readFileSync('eventsBsc.json'));
let jsonValuePolygon = JSON.parse(fs.readFileSync('eventsPolygon.json'));
var bscArray = [];
for(var i in jsonValueBsc)
bscArray.push([i, jsonValueBsc [i]]);
console.log(bscArray);
var polygonArray = [];
for(var i in jsonValuePolygon)
polygonArray.push([i, jsonValuePolygon [i]]);
console.log(polygonArray);
bscArray.map(x => console.log(x.args))
polygonArray.map(y => console.log(y.args))
'''
All is into async function

Related

What is the best way in nodejs to compare two different array of objects based on one or more attributes/fields? The fields name can be different

let obj1 = [{field1:11, field2:12, field3:13}, {field1:21, field2:22, field3:23}, {field1:31, field2:32, field3:33}, {field1:41, field2:42, field3:43}];
let obj2 = [{attribute1:21, attribute2:22}, {attribute1:31, attribute2:32}, {attribute1:11, attribute2:12}];
let output = [];
obj1.map(o1 => {
for (let i=0;i<obj2.length;i++) {
if (o1.field1 === obj2[i].attribute1) {
output.push(Object.assign(obj2[i], o1));
obj2.splice(i,1);
break;
}
}
});
console.log(output); //*[{attribute1:11,attribute2:12,field1:11,field2:12,field3:13},{attribute1:21,attribute2:22,field1:21,field2:22,field3:23},{attribute1:31,attribute2:32,field1:31,field2:32,field3:33}]*
The above code compares two different objects with its fields.
Here I am using 2 loops.
So my question is, do we have any better approach to achieve the same? Without two loops or using any package or the best way
You can use find to find the first element where the statement is true instead of looping and manually checking if the statement is true or false. Sadly find is also an iterative method but I don't see any other way to improve this. I am using filter to remove the elements that don't fulfil the condition o2.attribute1 === o1.field1.
let obj1 = [{field1:11, field2:12, field3:13}, {field1:21, field2:22, field3:23}, {field1:31, field2:32, field3:33}, {field1:41, field2:42, field3:43}];
let obj2 = [{attribute1:21, attribute2:22}, {attribute1:31, attribute2:32}, {attribute1:11, attribute2:12}];
const output = obj1.map(o1 => {
let obj2Value = obj2.find(o2 => o2.attribute1 === o1.field1);
return obj2Value ? Object.assign(obj2Value, o1) : null;
}).filter(o => o !== null);
console.log(output);
Alternatively you can use forEach to do this:
let obj1 = [{field1:11, field2:12, field3:13}, {field1:21, field2:22, field3:23}, {field1:31, field2:32, field3:33}, {field1:41, field2:42, field3:43}];
let obj2 = [{attribute1:21, attribute2:22}, {attribute1:31, attribute2:32}, {attribute1:11, attribute2:12}];
let output = [];
obj1.forEach(o1 => {
let obj2Value = obj2.find(o2 => o2.attribute1 === o1.field1);
obj2Value ? output.push(Object.assign(obj2Value, o1)) : '';
});
console.log(output);
There are several approaches to achieve this. Also remember map already returns a new array so no need to use push inside, just return. Check this for better understanding:
https://stackoverflow.com/questions/34426458/javascript-difference-between-foreach-and-map#:~:text=forEach%20%E2%80%9Cexecutes%20a%20provided%20function,every%20element%20in%20this%20array.%E2%80%9D .

error TS2538: Type 'CCCustomer' cannot be used as an index type

For below mentioned code facing error as error TS2538: Type 'CCCustomer' cannot be used as an index type.
with let index in ccCustomerList its working fine but in sonarqube received issue as Use "for...of" to iterate over this "Array". any alternative way available for this.
let data:Array<Customer>;
for (const index of CustomerList) {
const Customer = CustomerList[index];
const List: Array<string> = [];
In your loop, the index variable is not really an index of the array, but it's an object from the Customerlist, this is how for of works and that's why you get the error stating you can't use an object as an index.
So you don't need to get the customer from the CustomerList array since it's already there in your index variable.
Rename index to Customer and remove this line:
const Customer = CustomerList[index];
Replace all CustomerList[index] with Customer in your code.
Example
for (const Customer of CustomerList) {
const guidList: Array<string> = [];
// Use Customer object
More information
Update
If you need to use an index use a regular loop or add Array.entries() to the current loop which returns the index and the value (just remove it if not needed).
Example
for (const [index, value] of CustomerList.entries()) {
const Customer = CustomerList[index];
const guidList: Array<string> = [];

How to save one of JSON keys, using the method filter()?

I have implemented such a code. I only want to throw one key into the array under the name ("args"). Unfortunately my code returns in line 91 "TypeError: Cannot read properties of undefined (reading 'length')". How to fix it?
All is into async function :)
var objmapPolygon = {}, objmapBsc = {};
let jsonValueBsc = JSON.parse(fs.readFileSync('eventsBsc.json'));
let jsonValuePolygon = JSON.parse(fs.readFileSync('eventsPolygon.json'));
var mapped = jsonValuePolygon.map(
function (v) { for (var l in v) {this[l] = v[l];} },
objmapPolygon
);
console.log(objmapPolygon)
var mapps = jsonValueBsc.map(
function (v) { for (var l in v) {this[l] = v[l];} },
objmapBsc
);
console.log(objmapBsc)
const resultPolygon = mapps.filter(mapp => mapp.length < 7);
console.log(resultPolygon);
The .map() function returns an array filled with the values returned from the callback function. Your jsonValueBsc.map callback function does not return anything, so it is an array of the default return value undefined. When you access those array elements in mapps.filter(mapp => mapp.length < 7), mapp is undefined, thus you get an error.
Return something from the first mapping so there is a value, preferably an array so .length is meaningful.

Using GEE code editor to create unique values list from existing list pulled from feature

I'm working in the Google Earth Engine code editor. I have a feature collection containing fires in multiple states and need to generate a unique list of states that will be used in a selection widget. I'm trying to write a function that takes the list of state values for all fires, creates a new list, and then adds new state values to the new unique list. I have run the code below and am not getting any error messages, but the output is still statesUnique = []. Can anyone point me in the right direction to get the new list to populate with unique values for states?
My Code:
// List of state property value for each fire
var states = fire_perim.toList(fire_perim.size()).map(function(f) {
return ee.Feature(f).get('STATE');
}).sort();
print('States: ', states);
// Create unique list function
var uniqueList = function(list) {
var newList = []
var len = list.length;
for (var i = 0; i < len; i++) {
var j = newList.contains(list[i]);
if (j === false) {
newList.add(list[i])
}
}
return newList
};
// List of unique states
var statesUnique = uniqueList(states);
print('States short list: ', statesUnique)
Okay, I did not come up with this answer, some folks at work helped me, but I wanted to post the answer so here is one solution:
var state_field = 'STATE'
var all_text = 'All states'
// Function to build states list
var build_select = function(feature_collection, field_name, all_text) {
var field_list = ee.Dictionary(feature_collection.aggregate_histogram(field_name))
.keys().insert(0, all_text);
return field_list.map(function(name) {
return ee.Dictionary({'label': name, 'value': name})
}).getInfo();
};
var states_list = build_select(fire_perim, state_field, all_text)
print(states_list)

Concurrently iterate over two iterables of same length

I have two iterables of the same length that I need to loop over at the same time. One iterable is a Map of custom objects, and the other is an array of objects. I need to add the contents of the array into the Map (via some helper prototype functions), preferably asynchronously and concurrently. Also, the two containers are associated to each other based on their order. So the first element in the array needs to be added to the first element in the Map.
If I was to do this synchronously it would look something like this:
var map;
var arr;
for (var i = 0; i < arr.length; i++) {
// get our custom object, call its prototype helper function with the values
// in the array.
let customObj = map[i];
customObj.setValues(arr[i])
}
Typically to loop over arrays async and concurrently I use bluebirds Promise.map. It would look something like this:
var arr
Promise.map(arr, (elem) => {
// do whatever I need to do with that element of the array
callAFunction(elem)
})
It would be awesome if I could do something like this:
var map;
var arr;
Promise.map(map, arr, (mapElem, arrElem) {
let customObj = mapElem[1];
customObj.setValue(arrElem);
})
Does anyone know of a library or a clever way to help me accomplish this?
Thanks.
EDIT: Just want to add some clarification on the objects stored in the map. The map is keyed on a unique value, and values are associated with that unique values are what make up this object. It is defined in a similar manner to this:
module.exports = CustomObject;
function CustomObject(options) {
// Initialize CustomObjects variables...
}
CustomObject.prototype.setValue(obj) {
// Logic for adding values to object...
}
if you already know, that the Map (I assume you really mean the JavaScript Map here, which is ordered) and the array have the same length, you do not need a mapping function, that takes both the array AND the map. One of both is enough, because the map function also gives you an index value:
var map;
var arr;
Promise.map(map, (mapElem, index) => {
let customObj = mapElem[1];
customObj.setValue(arr[index]);
});
You can use the function Promise.all that execute all the given asynchronous functions.
You should know that actually node.js support fully Promises, you do not need bluebirds anymore.
Promise.all(arr.map(x => anyAsynchronousFunc(x)))
.then((rets) => {
// Have here all return of the asynchronous functions you did called
// You can construct your array using the result in rets
})
.catch((err) => {
// Handle the error
});

Resources