get all values from dictionary - linq.js

I'm using linqjs in my website and I'm trying to get all values of a dictionary populated with toDictionary() library extension.
Here is my code:
var imagesDictionary = Enumerable.from(data)
.select(function (x) {
var images = Enumerable.from(x.ImagesSections)
.selectMany(function (y) {
return Enumerable.from(y.Images)
.select(function (z) {
return z.Thumb;
});
})
.toArray();
return { Title: x.Title, Images: images };
})
.toDictionary("$.Title", "$.Images");
var imagesToPreload = imagesDictionary.toEnumerable()
.selectMany("$.Value");
I would that imagesToPreload become an array of all images contained in the dictionary but I can't understand how to do that and this:
var imagesToPreload = imagesDictionary.toEnumerable()
.selectMany("$.Value");
seems the way than everyone used to obtain that.
Could someone help me?

Since it appears you're using the linqjs 3 beta version, the format of the entries have changed. The properties are in lowercase now.
var imagesDictionary = Enumerable.from(data)
.toDictionary("$.Title",
"Enumerable.from($.ImagesSections).selectMany('$.Images', '$$.Thumb').toArray()"
);
var imagesToPreload = imagesDictionary.toEnumerable()
.selectMany("$.value") // lowercase 'value'
.toArray();

Related

Best way to search march in an array of JavaScript Objects?

I'm facing a challenge to match values within an array of JS objects. Let me give you an example,
var dynamicObjectArray = [
{Id: 1422859025, FromTime: "2023-02-12T19:00:00Z", ToTime: "2023-02-12T20:00:00Z"},
{Id: 1422859027, FromTime: "2023-02-12T18:00:00Z", ToTime: "2023-02-12T19:00:00Z"}
]
I need to find all Ids for FromTime or ToTime match with "2023-02-12T19:00:00Z"
Using a database, it can be done easily. But, here, I need to play an array of 100 objects max. Also, data will be dynamic. Can you please suggest me a way to achieve the goal using NodeJS.
You could use the JS Date builtin constructor to compare dates instead of using the string directly.
Filter your matching objects, and map the ids.
You can do something like this.
const dynamicObjectArray = [{
Id: 1422859025,
FromTime: "2023-02-12T19:00:00Z",
ToTime: "2023-02-12T20:00:00Z"
},
{
Id: 1422859027,
FromTime: "2023-02-12T18:00:00Z",
ToTime: "2023-02-12T19:00:00Z"
}
];
const matchTime = new Date("2023-02-12T19:00:00Z").getTime();
const matchIds = dynamicObjectArray.filter(obj => {
const fromTime = new Date(obj.FromTime).getTime();
const toTime = new Date(obj.ToTime).getTime();
return matchTime === fromTime || matchTime === toTime;
}).map(obj => obj.Id);
console.log(matchIds);
If you want a suggestion, you can do something like this:
Create a function that takes as a parameter, the wanted Date
Create a variable containing an array where you will save all those "id's" that match your condition
Create a for loop
Create an if condition, that matches the following condition:
if date exists on "FromTime" or exists on "ToTime", push to your "id's array"
Return your ids array
Here is the code implementation:
function filterObjByDate(TO_MATCH_DATE) {
let ids = [];
for (let i = 0; i < dynamicObjectArray.length; i++) {
if (
dynamicObjectArray[i].FromTime === TO_MATCH_DATE ||
dynamicObjectArray[i].ToTime === TO_MATCH_DATE
) {
ids.push(dynamicObjectArray[i].Id);
}
}
return ids
}
That's it. If you have more question, ask me 😀👍

Get Date from Nested Array of Objects and set that date as an Key in Node.js

I'm using Node.js I have data like this:
const data= [
{"id":"1","date":"2022-09-07T15:56:32.279Z","req_id":"98"},
{"id":"2","date":"2022-09-08T15:48:19.075Z","req_id":"97"},
{"id":"3","date":"2022-09-06T15:48:19.073Z","req_id":"96"}
{"id":"4","date":"2022-09-06T15:48:19.073Z","req_id":"96"}
]
I want data in this format:
expected Output:
"2022-09-06":[
{"id":"4","date":"2022-09-06T15:48:19.073Z","req_id":"96"},
{"id":"3","date":"2022-09-06T15:48:19.073Z","req_id":"96"}
]
"2022-09-08":[
{"id":"2","date":"2022-09-08T15:48:19.075Z","req_id":"97"}
]
"2022-09-07":[
{"id":"1","date":"2022-09-07T15:56:32.279Z","req_id":"98"}
]
Assuming the dates are always in the same format, I would do something like this:
function mapData(data){
// returns the given date as an string in the "%dd-%mm-%yyyy" format
const getDateWithoutTime = (dateString) => dateString.split("T")[0];
const mappedData = [];
for(const req of data){
const formattedDate = getDateWithoutTime(req.date);
// if the key already exists in the array, we add a new item
if(mappedData[formattedDate]) mappedData[formattedDate].push(req);
// if the key doesn't exist, we create an array with that single item for that key
else mappedData[formattedDate] = [req];
}
return mappedData;
}
Straightforward solution using regex:
let result = new Map();
for (const item of data) {
let date = item['date'].match(/\d{4}-\d{2}-\d{2}/)[0];
let items = result.get(date) || [];
items.push(item);
result.set(date, items)
}

How to return the array after altering it back into json format?

I am making a discord bot where you can use the command tcp freeitem to obtain your free item.
I am trying to alter that value of an Account by adding a new item object into the account. When I map the array to replace a value, it erases the name (allAccounts) of the array of the json. More information below. Here is what I have:
const listOfAllItemNames = require(`C:/Users///censored///OneDrive/Desktop/discord bot/itemsDataList.json`)
const accountList = require(`C:/Users///censored///OneDrive/Desktop/discord bot/account.json`)
const fs = require('fs')
var accountThatWantsFreeItem = accountList.allAccounts.find(user => message.author.id === user.userId);
var randomFreeItem = listOfAllItemNames.allItems[Math.floor(Math.random() * listOfAllItemNames.allItems.length)]
if(accountThatWantsFreeItem === undefined) {message.reply('You need to make an account with tcp create!'); return; }
if(accountThatWantsFreeItem.freeItem === true) {message.reply('You already got your free one item!'); return;}
fs.readFile('C:/Users///censored///OneDrive/Desktop/discord bot/account.json', 'utf8', function readFileCallback(err,data) {
if(err){
console.error(err)
} else {
var accountsArray = JSON.parse(data)
console.log(accountsArray)
var whoSentCommand = accountsArray.allAccounts.find(user => message.author.id === user.userId)
whoSentCommand.Items.push(randomFreeItem)
whoSentCommand.freeItem = true;
var test = accountsArray.allAccounts.map(obj => whoSentCommand === obj.id || obj)
//I believe the issue is trying to map it returns a new array
console.log(test)
test = JSON.stringify(test, null, 5)
//fs.writeFile('C:/Users///censored///OneDrive/Desktop/discord bot/account.json', test, err =>{ console.error(err)} )
}
})
when I write the file back to json file, it removes the "allAccounts" identifier in this file
//json file
//array name "allAccounts" is removed, I need this still here for code to work
{
"allAccounts" : [
{
"userId": "182326315813306368",
"username": "serendipity",
"balanceInHand": 0,
"balanceInBank": 0,
"freeItem": false,
"Items": []
},
(No "allAccounts" array name)
to this: output after writing file
So, the final question is
How would I alter the array so that I only alter the account I want without editing the array name?
Please feel free to ask any questions if I was unclear.
Array.map() method returns the converted array.
So in the below line, map() method takes allAccounts array and perform actions and put the target array (not object) to the test variable.
var test = accountsArray.allAccounts.map(obj => whoSentCommand === obj.id || obj)
So for making code works, please change the code like this:
var test = {
"accountsArray": accountsArray.allAccounts.map(obj => whoSentCommand === obj.id || obj)
}
When posting questions, please please reduce the code to a minimal example that will demonstrate the problem, and use words, not code, to describe the problem.
It looks like you are expecting .map to do something other than what it does.
Please consult the documentation for Array.map().
It takes the array that you pass it (in this case accountsArray.allAccounts) and transforms it, returning the transformed array.
You have essentially done test = accountsArray.allAccounts but for some reason are expecting test to contain an Object with the key allAccounts, when in fact it will only contain an Array, because that is what you have assigned it.

How to remove same named objects from a JSON structure, but with a non uniform pattern in structure?

I have a json structure, that is a bit odd, this is returned from a remote device, and I have to accept it as is. For example...
{"_":"e6a7f749","4321013c":{"_":"5d839a60"},"67ea44a0":{"_":"ec7500f9"},"6bea5f08":{"_":"ecdaead4"},"1e92311e":{"_":"5348dab3"}}
I need to remove the '_' key-value pairs, but retain everything else, such that...
{"4321013c":,"67ea44a0":,"6bea5f08":,"1e92311e":,}
As you can see, this leaves just some 'keys', from the original structure. I then want to convert the 'keys' to a simple array of values. Such...
["4321013c","67ea44a0","6bea5f08","1e92311e"]
All this done in node.js (JavaScript) by the way.
Here is my solution. I am not sure if I fully understood the question though.
But here I traverse the object, an gather up all the keys and values into another, flattened object. Then finally, I run Object.keys on that and remove any "_" values.
const obj = {
"_":"e6a7f749",
"4321013c":{"_":"5d839a60"},
"67ea44a0":{"_":"ec7500f9"},
"6bea5f08":{"_":"ecdaead4"},
"1e92311e":{"_":"5348dab3"}
};
const collectValues = (root) => {
return Object.keys(root).reduce((map, key) => {
const value = root[key];
if (typeof value === 'string') {
map = {
...map,
[key]: true,
[value]: true
};
} else {
const nestedValues = collectValues(root[key]);
map = {
...map,
...nestedValues,
[key]: true
};
}
return map;
}, {});
}
const uniqueArray = Object.keys(collectValues(obj)).filter(v => v !== '_');
console.log(uniqueArray);

Convert geojson polygons into points with node using query-overpass and turf.js

I use the node module "query-overpass" for a query to get farmshops from openstreetmaps. I would like to convert all polygons to points inside this script. I use turf.js to get the centroids of theese polygons, but I am not able to change the objects in a permanent way. This is my code so far:
const query_overpass = require("query-overpass");
const turf = require ("turf");
const fs = require("fs")
let test
let filename = "data/test.js"
let bbox = "48.91821286473131,8.309097290039062,49.0610446187357,8.520584106445312";
console.log('starting query for ' +filename)
console.log('bbox: ' +bbox)
let query = `
[out:json][timeout:250];
// gather results
(
// query part for: “vending=milk”
node["vending"="milk"](${bbox});
way["vending"="milk"](${bbox});
relation["vending"="milk"](${bbox});
// query part for: “shop=farm”
node["shop"="farm"](${bbox});
way["shop"="farm"](${bbox});
relation["shop"="farm"](${bbox});
// query part for: “vending=food”
node["vending"="food"](${bbox});
way["vending"="food"](${bbox});
relation["vending"="food"](${bbox});
);
// print results
out body;
>;
out skel qt;
`;
// query overpass, write result to file
query_overpass(query, (error, data) => {
data = JSON.stringify(data , null, 1)
console.log(data)
test = JSON.parse(data)
//create centroids for every polyon and save them as a point
for (var i = 0; i < test.features.length; i++) {
console.log("Log: " +test.features[i].geometry.type)
console.log("Log: " +test.features[i].properties.name)
if (test.features[i].geometry.type === "Polygon"){
console.log("polygon detected")
var centroid = turf.centroid(test.features[i]);
var lon = centroid.geometry.coordinates[0];
var lat = centroid.geometry.coordinates[1];
console.log(" lon: " +lon +" lat: " +lat)
test.features[i].geometry.type = 'Point'
//delete Polygon structure and insert centroids as new points here
console.log("polygon deleted and changed to point")
}
}
console.log(test)
fs.writeFile(filename, `var file = ${test};` , ["utf-8"], (error, data) => {if (error) {console.log(error)}})
}, {flatProperties: true}
)
It seems like I can change things inside of the for loop, but they do not appear when the data is saved later. It is basically a question of how to edit json objects properly, but I can't figure out why this doesnt work here at all.
So there are basically two questions:
Why cant I override geometry.type in the example above?
How can I delete the old polygon and add a new point to a feature?
Thanks for any help.
That's quite complicated... Why don't you let Overpass API do this job and use out center; instead of out body;>;out skel qt; to return the center points of all nodes, ways and relations. You can use overpass-turbo.eu to try this out first.

Resources