Related
I have an array of dates that I use for mapping. When trying to pass items from a different array (names) using the index, I get undefined values because the "names" array has less entries than the index (dates).
I have a third array with what should be the correct format (format):
let names = [
"chair",
"table",
"door",
"window",
"glass",
"wine",
"car",
"keys",
"dream",
"keyboard",
"vodka",
"pepsi",
"bag",
"ikea",
"mercedes",
"soprano"
];
let format = [3, 3, 1, 5, 4, 4, 3, 5, 13, 10, 3, 5, 5, 2, 2, 10];
let dates = [
"2021-10-04T04:00:00.000Z",
"2021-10-05T04:00:00.000Z",
"2021-10-06T04:00:00.000Z",
"2021-10-13T04:00:00.000Z",
"2021-10-14T04:00:00.000Z",
"2021-10-15T04:00:00.000Z",
"2021-10-15T04:00:00.000Z",
"2021-10-17T22:00:00.000Z",
"2021-10-18T22:00:00.000Z",
"2021-10-19T22:00:00.000Z",
"2021-10-20T22:00:00.000Z",
"2021-10-21T22:00:00.000Z",
"2021-10-17T22:00:00.000Z",
"2021-10-18T22:00:00.000Z",
"2021-10-19T22:00:00.000Z",
"2021-10-20T22:00:00.000Z",
"2021-10-19T04:00:00.000Z",
"2021-10-20T04:00:00.000Z",
"2021-10-21T04:00:00.000Z",
"2021-10-22T04:00:00.000Z",
"2021-10-19T04:00:00.000Z",
"2021-10-20T04:00:00.000Z",
"2021-10-21T04:00:00.000Z",
"2021-10-25T04:00:00.000Z",
"2021-10-26T04:00:00.000Z",
"2021-10-27T04:00:00.000Z",
"2021-10-28T04:00:00.000Z",
"2021-10-29T04:00:00.000Z",
"2021-10-25T04:00:00.000Z",
"2021-10-26T04:00:00.000Z",
"2021-10-27T04:00:00.000Z",
"2021-10-28T04:00:00.000Z",
"2021-10-29T04:00:00.000Z",
"2021-11-01T04:00:00.000Z",
"2021-11-02T04:00:00.000Z",
"2021-11-03T04:00:00.000Z",
"2021-11-04T04:00:00.000Z",
"2021-11-05T04:00:00.000Z",
"2021-11-08T04:00:00.000Z",
"2021-11-09T04:00:00.000Z",
"2021-11-10T04:00:00.000Z",
"2021-11-01T04:00:00.000Z",
"2021-11-02T04:00:00.000Z",
"2021-11-03T04:00:00.000Z",
"2021-11-04T04:00:00.000Z",
"2021-11-05T04:00:00.000Z",
"2021-11-08T04:00:00.000Z",
"2021-11-09T04:00:00.000Z",
"2021-11-10T04:00:00.000Z",
"2021-11-11T04:00:00.000Z",
"2021-11-12T04:00:00.000Z",
"2021-11-11T04:00:00.000Z",
"2021-11-12T04:00:00.000Z",
"2021-11-13T04:00:00.000Z",
"2021-11-15T04:00:00.000Z",
"2021-11-16T04:00:00.000Z",
"2021-11-17T04:00:00.000Z",
"2021-11-18T04:00:00.000Z",
"2021-11-19T04:00:00.000Z",
"2021-11-16T04:00:00.000Z",
"2021-11-17T04:00:00.000Z",
"2021-11-18T04:00:00.000Z",
"2021-11-19T04:00:00.000Z",
"2021-11-20T04:00:00.000Z",
"2021-11-23T04:00:00.000Z",
"2021-11-24T04:00:00.000Z",
"2021-11-23T04:00:00.000Z",
"2021-11-24T04:00:00.000Z",
"2022-01-05T04:00:00.000Z",
"2022-01-06T04:00:00.000Z",
"2022-01-07T04:00:00.000Z",
"2022-01-10T04:00:00.000Z",
"2022-01-11T04:00:00.000Z",
"2022-01-12T04:00:00.000Z",
"2022-01-13T04:00:00.000Z",
"2022-01-14T04:00:00.000Z",
"2022-01-17T04:00:00.000Z",
"2022-01-18T04:00:00.000Z"
];
let app_multiple = dates.map(function combineTitleData(dataItem, index) {
return {
text: 'LR' + dates[index] + ': ' + names[index],
};
});
console.log(app_multiple);
What I would like to achieve is using the "format" array is to follow the patern and use this array to construct the mapping.
The format contains: [3, 3, 1, 5, 4, 4, 3, 5, 13, 10, 3, 5, 5, 2, 2, 10];
I would like to use in the mapping the "names" array like this:
(chair) -> 3 times
(table) -> 3 times
(door) -> 1 time
(window) -> 5 times
(glass) -> 4 times
.... etc
So the output would be like this:
[
{
"text": "LR2021-10-04T04:00:00.000Z: chair"
},
{
"text": "LR2021-10-05T04:00:00.000Z: chair"
},
{
"text": "LR2021-10-06T04:00:00.000Z: chair"
},
{
"text": "LR2021-10-13T04:00:00.000Z: table"
},
{
"text": "LR2021-10-14T04:00:00.000Z: table"
},
{
"text": "LR2021-10-15T04:00:00.000Z: table"
},
{
"text": "LR2021-10-15T04:00:00.000Z: door"
},
{
"text": "LR2021-10-17T22:00:00.000Z: window"
},
{
"text": "LR2021-10-18T22:00:00.000Z: window"
},
{
"text": "LR2021-10-19T22:00:00.000Z: window"
},
{
"text": "LR2021-10-20T22:00:00.000Z: window"
},
{
"text": "LR2021-10-21T22:00:00.000Z: window"
}
.... etc
.... etc
]
Is this possible to do? Thanks.
The first option is:
var numTimesUsed = 0;
var nameIndex = 0;
let app_multiple = dates.map(function combineTitleData(dataItem, index) {
if(format[nameIndex] == numTimesUsed) {
nameIndex++;
numTimesUsed = 0;
}
numTimesUsed++;
return {
text: 'LR' + dates[index] + ': ' + names[nameIndex],
};
});
The second option is (I'm looping through the names map instead of dates for this option):
var dateIndex = 0;
let app_multiple = names.map(function combineTitleData(nameItem, index) {
var datesForName = [];
for(var i = 0; i < format[index]; i++) {
datesForName[i] = {
text: 'LR' + dates[dateIndex] + ': ' + names[index],
};
dateIndex++;
}
return datesForName;
});
You could probably also use some math to avoid extra variables in the second option, but its easier to just have an extra variable.
I am working on a multiplayer game and I have a room array with the following layout (I added comments for better understanding):
Room_Array
[
[
"Room_0", // room name
10, // max people
"Random", // room type
[ // now arrays of players follow
[
1, // ShortID
123, // position X
234, // position Y
10 // angle
],
[
2,
123,
234,
10
],
[
3,
123,
234,
10
],
]
]
// here other rooms are created with the same layout as Room_0 when the max people is reached
]
How would I go around to remove the whole array of the player with ShortID = 2? in case he disconnects?
So the desired result would be:
Room_Array
[
[
"Room_0", // room name
10, // max people
"Random", // room type
[ // now arrays of players follow
[
1, // ShortID
123, // position X
234, // position Y
10 // angle
],
[
3,
123,
234,
10
],
]
]
]
I tried the following code and in the console log it showed me the elements of the array I need to splice, so 2, 123, 234, 10. The commented splice resulted in error unidentified element 1.
for (var i = 0; i < Room_Array.length; i++)
{
if (Room_Array[i][0] === PlayerObject[socket.id].RoomName)
{
for (var j = 0; j < Room_Array[i][3].length; j++)
{
if (Room_Array[i][3][j][0] === PlayerObject[socket.id].ShortID)
{
console.log("Array to splice: " + Room_Array[i][3][j]);
//Room_Array.splice([i][3][j], 1); // error unidentified 1
}
}
break;
}
}
Here is a working solution that mutates the initial array.
const Room_Array = [
[
"Room_0", // room name
10, // max people
"Random", // room type
[ // now arrays of players follow
[
1, // ShortID
123, // position X
234, // position Y
10 // angle
],
[
2, // ShortID
123, // position X
234, // position Y
10 // angle
],
[
3,
123,
234,
10
],
]
]
];
function removeUser (array, id) {
array.forEach(room => {
const [roomName, maxPeople, roomType, players] = room;
const index = players.findIndex(([shortId]) => shortId === id);
if(index > -1) {
players.splice(index, 1);
}
});
}
removeUser(Room_Array, 2);
console.log(Room_Array);
Using foreach modifying the existing array
let Room_Array=[["Room_0", 10, "Random",[[ 1,123,234,10],[2,123,234,10],[3,123,234, 10]],]];
function remove(id){
Room_Array.forEach( room => room[3].splice(room[3].findIndex( rm=>rm[0]==id),1))
};remove(2);
console.log(Room_Array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using map returning a new array
let Room_Array=[["Room_0", 10, "Random",[[ 1,123,234,10],[2,123,234,10],[3,123,234, 10]],]];
function remove(id){
return Room_Array.map( room => {room[3].splice(room[3].findIndex( rm=>rm[0]==id),1);return room;})
}
console.log(remove(2));
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you want to go down the JSON route instead, which I highly recommend, here's a working example:
const Room_Array =
[
{
roomName: "Room_0",
maxPeope: 10,
roomType: "Random",
players: [
{
shortID: 1,
xPosition: 123,
yPosition: 234,
angle: 10
},
{
shortID: 2,
xPosition: 123,
yPosition: 234,
angle: 10
},
{
shortID: 3,
xPosition: 123,
yPosition: 234,
angle: 10
},
]
}
];
function removeUser(id)
{
Room_Array.forEach((room) =>
{
room.players = room.players.filter(player => player.shortID !== id);
});
console.log(Room_Array);
}
removeUser(1);
Maybe this question has already been asked and answered somewhere but after searching for more than 3 hrs I'm asking this question.
Below is my JSON data
var my_data = [
{
"TempRture_qc": 4,
"VoltAGE": 44.09722,
"TempRture": 22.32,
"VoltAGE_qc": 55,
"_time": "2018-08-07T03:39:29.001Z"
},
{
"TempRture_qc": 2,
"VoltAGE": 42.09722,
"TempRture": 22.12,
"VoltAGE_qc": 0,
"_time": "2018-08-07T03:39:30.006Z"
},
{
"TempRture_qc": 1,
"VoltAGE": 43.09722,
"TempRture": 22.82,
"VoltAGE_qc": 0,
"_time": "2018-08-07T03:39:31.009Z"
}
];
desired output i need
[
{
"name": "TempRture_qc",
"data": [
{"name":"2018-08-07T03:39:29.001Z","y":4},
{"name":"2018-08-07T03:39:30.006Z","y":2},
{"name":"2018-08-07T03:39:33.017Z","y":1}
]
},
{
"name": "VoltAGE",
"data": [
{"name":"2018-08-07T03:39:29.001Z","y":44.09722},
{"name":"2018-08-07T03:39:30.006Z","y":42.09722},
{"name":"2018-08-07T03:39:33.017Z","y":43.09722}
]
},
{
"name": "TempRture",
"data": [
{"name":"2018-08-07T03:39:29.001Z","y":22.32},
{"name":"2018-08-07T03:39:30.006Z","y":22.12},
{"name":"2018-08-07T03:39:33.017Z","y":22.82}
]
},
{
"name": "VoltAGE_qc",
"data": [
{"name":"2018-08-07T03:39:29.001Z","y":55},
{"name":"2018-08-07T03:39:30.006Z","y":0},
{"name":"2018-08-07T03:39:33.017Z","y":0}
]
}
]
for getting this above output i have tried below code.
var accounting = [];
var fieldName = {};
for (var x in obj){
var mykey = Object.keys(obj[x]);
for (var mk in mykey){
if(mykey[mk]=='VoltAGE'){
fieldName.name = mykey[mk];
// accounting.push({
// "name":mykey[mk]
// })
}
if(mykey[mk]=='TempRture'){
fieldName.name = mykey[mk];
}
// console.log(mykey[mk]); //to get the key name
}
accounting.push({
"name" : obj[x]._time,
"y" : obj[x][employees.name],
})
fieldName.data = accounting;
}
console.log(fieldName );
by doing this what I'm getting is below JSON
{ name: 'TempRture',
data:
[ { name: '2018-08-07T03:39:29.001Z', y: 22.32 },
{ name: '2018-08-07T03:39:32.014Z', y: 22.12 },
{ name: '2018-08-07T03:39:33.017Z', y: 22.82 } ] }
I'm not able to understand how I will get the data in one JSON object.
For a solution with low time complexity, try .reduceing into an object indexed by keys of the inner object, creating a { name, data: [] } at that key in the accumulator if it doesn't exist there yet. Then, push to the data array, and get the values of the whole object:
var my_data=[{"TempRture_qc":4,"VoltAGE":44.09722,"TempRture":22.32,"VoltAGE_qc":55,"_time":"2018-08-07T03:39:29.001Z"},{"TempRture_qc":2,"VoltAGE":42.09722,"TempRture":22.12,"VoltAGE_qc":0,"_time":"2018-08-07T03:39:30.006Z"},{"TempRture_qc":1,"VoltAGE":43.09722,"TempRture":22.82,"VoltAGE_qc":0,"_time":"2018-08-07T03:39:31.009Z"}]
console.log(Object.values(
my_data.reduce((a, { _time, ...obj }) => {
Object.entries(obj).forEach(([name, val]) => {
if (!a[name]) a[name] = { name, data: [] };
a[name].data.push({ name: _time, y: val });
});
return a;
}, {})
));
var my_data=[{"TempRture_qc":4,"VoltAGE":44.09722,"TempRture":22.32,"VoltAGE_qc":55,"_time":"2018-08-07T03:39:29.001Z"},{"TempRture_qc":2,"VoltAGE":42.09722,"TempRture":22.12,"VoltAGE_qc":0,"_time":"2018-08-07T03:39:30.006Z"},{"TempRture_qc":1,"VoltAGE":43.09722,"TempRture":22.82,"VoltAGE_qc":0,"_time":"2018-08-07T03:39:31.009Z"}]
var keys = Object.keys(my_data[0])
var result= [];
for(i = 0; i<keys.length-1; i++) {
var obj = {name: keys[i],data: []}
obj.data = my_data.map(val=>({name: val["_time"], y: val[keys[i]]}));
result.push(obj);
}
console.log(result)
An understandable answer with map, findIndex and forEach functions will be
var my_data = [{ "TempRture_qc": 4, "VoltAGE": 44.09722, "TempRture": 22.32, "VoltAGE_qc": 55, "_time": "2018-08-07T03:39:29.001Z" }, { "TempRture_qc": 2, "VoltAGE": 42.09722, "TempRture": 22.12, "VoltAGE_qc": 0, "_time": "2018-08-07T03:39:30.006Z" }, { "TempRture_qc": 1, "VoltAGE": 43.09722, "TempRture": 22.82, "VoltAGE_qc": 0, "_time": "2018-08-07T03:39:31.009Z" } ],
result = [];
my_data.map(itm => {
let keys = Object.keys(itm);
keys.forEach(iitt => {
if (iitt != '_time') {
let index = result.findIndex(ii => {
return ii.name == iitt;
})
if (index == -1) {
result.push({
name: iitt,
data: []
});
result[result.length - 1].data.push({
name: itm["_time"],
y: itm[iitt]
})
} else {
result[index].data.push({
name: itm["_time"],
y: itm[iitt]
});
}
}
})
})
console.log(result)
I need to sort my array, he is like this:
x = {
'Abr/2017': [ { id: 1 } ],
'Fev/2018': [ { id: 1 } ],
'Jul/2017': [ { id: 1 } ],
'Abr/2018': [ { id: 1 } ],
'Fev/2017': [ { id: 1 } ],
'Jul/2018': [ { id: 1 } ],
'Dez/2019': [ { id: 1 } ]
}
and I need him to be sorted first in the year and then in the months
Because your data is represented as object, you have to convert it to array as a first step. Then you can sort. Later you can map result array to whatever you want.
Important thing is that if you want to keep this data in some order then you have to use array structure
let x = {
'Abr/2017': [ { id: 1 } ],
'Fev/2018': [ { id: 1 } ],
'Jul/2017': [ { id: 1 } ],
'Abr/2018': [ { id: 1 } ],
'Fev/2017': [ { id: 1 } ],
'Jul/2018': [ { id: 1 } ],
'Dez/2019': [ { id: 1 } ]
}
// this function transform your object to array representation
// where your actual key (e.g. Fev/2017) is stored in helper
// property called key
function toArray(obj) {
return Object.keys(obj).reduce((arr, key) => {
arr.push({ key, data: obj[key] })
return arr
}, [])
}
function byYearAndMonth() {
// month definition - help with sorting
let monthOrder = {
'Jan': 1,
'Fev': 2,
'Mar': 3,
'Abr': 4,
'Mai': 5,
'Jun': 6,
'Jul': 7,
'Ago': 8,
'Set': 9,
'Out': 10,
'Nov': 11,
'Dez': 12
}
let mapDate = function([month, year]) {
return [monthOrder[month], Number(year)]
}
// actual sorting function
return function(a, b) {
const [aMonth, aYear] = mapDate(a.key.split('/'))
const [bMonth, bYear] = mapDate(b.key.split('/'))
if(aYear < bYear) {
return -1
}
if(aYear > bYear) {
return 1
}
if(aMonth < bMonth) {
return -1
}
if(aMonth > bMonth) {
return 1
}
return 0
}
}
// lets try how it works
let xArray = toArray(x)
xArray.sort(byYearAndMonth());
var result = xArray.map(x => x)
// with map (or reduce) you can transform it to whatever you want
// I'm just returning exactly the same object
console.log(result)
I am using a cartesian product function that given [1], [1,2,3], [1,2,3] returns 9 combinations:
[ [ 1, 1, 1 ],
[ 1, 2, 1 ],
[ 1, 3, 1 ],
[ 1, 1, 2 ],
[ 1, 2, 2 ],
[ 1, 3, 2 ],
[ 1, 1, 3 ],
[ 1, 2, 3 ],
[ 1, 3, 3 ] ]
But I need to remove those with the same items regardless of the order, so [ 1, 3, 1 ] and [ 1, 1, 3 ] are the same to me. The result should contain 6 items:
[ [ 1, 1, 1 ],
[ 1, 2, 1 ],
[ 1, 3, 1 ],
[ 1, 2, 2 ],
[ 1, 3, 2 ],
[ 1, 3, 3 ] ]
I can write a function that compares all possible pairs with _.xor, but for larger numbers it will probably be very inefficient. Is there a good way in Javascript to do this? An efficient way to compare all possible pairs or an algorithm for cartesian product without duplicates?
sort each array of the cartesian product
[ 1, 2, 1 ] -> [1 , 1 , 2]
[ 1, 1, 2 ] -> [1 , 1 , 2]
then gather these sorted arrays into a set, that will remove the duplicates.
Of course, you can do that while constructing the cartesian product rather than afterward.
JavaScript has Set and Map, however they compare objects and arrays by reference rather than by value, so you cannot take advantage of it directly. The idea is to use a key function which sorts and json encodes the items before putting it in a set.
pure ES5:
function product(sets) {
if (sets.length > 0) {
var head = sets[0];
var tail = product(sets.slice(1));
var result = [];
head.forEach(function(x) {
tail.forEach(function(xs) {
var item = xs.slice(0);
item.unshift(x);
result.push(item);
});
});
return result;
} else {
return [[]];
}
}
function myKeyFn(item) {
return JSON.stringify(item.slice(0).sort());
}
function uniqBy(items, keyFn) {
var hasOwn = Object.prototype.hasOwnProperty, keyset = {};
return items.filter(function(item) {
var key = keyFn(item);
if (hasOwn.call(keyset, key)) {
return false;
} else {
keyset[key] = 1;
return true;
}
});
}
function uniqProduct(sets) {
return uniqBy(product(sets), myKeyFn);
}
function log(x) {
console.log(x);
var pre = document.createElement('pre');
pre.appendChild(document.createTextNode(x));
document.body.appendChild(pre);
}
log(uniqProduct([[1],[1,2,3],[1,2,3]]).map(JSON.stringify).join("\n"));
<pre></pre>
lodash + modern JavaScript:
// Note: This doesn't compile on current babel.io/repl due to a bug
function product(sets) {
if (sets.length > 0) {
const [x, ...xs] = sets;
const products = product(xs);
return _.flatMap(x, head => products.map(tail => [head, ...tail]));
} else {
return [[]];
}
}
function uniqProduct(sets) {
return _.uniqBy(product(sets), x => JSON.stringify(x.slice(0).sort()));
}
console.log(uniqProduct([[1],[1,2,3],[1,2,3]]).map(JSON.stringify).join("\n"));
JavaScript has set data structure.
So store your results in a set where each element of the set is a collection of pairs of numbers from the original sets along with the number of times that number occurs.
So your result would look something like this:
[
{1:3},
{1:2, 2: 1},
{ 1:2, 3:1},
{ 1:1, 2:2},
{ 1:1, 2:1, 3:1},
{ 1:1, 3:2 } ]
This way, you won't be able to add the object a second time to the set.