Related
I have an array containing hundreds sometimes thousands of objects with vectors of 3D objects. There are three or even more identical objects in the array (I think they are needed also for the render to know which side the normals of the surface are facing) but for what I want to do I need the identical objects gone. The bad part is, I cant just check one value since sometimes two objects share for example the same value for x but then the y or z is different. Is there an efficient way to do that? Unfortunately all tutorials I found deal with checking for one value and I need to check all of them.
const vectors = [
{x: 6.869495194905539e-9, y: -0.11905603855848312, z: -0.3318425416946411},
{x: 6.869495194905539e-9, y: -0.11905603855848312, z: -0.3318425416946411},
{x: 6.869495194905539e-9, y: -0.11905603855848312, z: -0.3318425416946411},
{x: 0.06476999074220657, y: -0.11905603855848312, z: -0.3254662752151489},
{x: 0.06476999074220657, y: -0.11905603855848312, z: -0.3254662752151489},
{x: 0.06476999074220657, y: -0.11905603855848312, z: -0.3254662752151489},
{x: 0.06476999074220657, y: -0.11905603855848312, z: -0.3254662752151489},
{x: 0.12705090641975403, y: -0.11905603855848312, z: -0.306582510471344},
{x: 0.12705090641975403, y: -0.11905603855848312, z: -0.306582510471344},
{x: 0.12705090641975403, y: -0.11905603855848312, z: -0.306582510471344},
etc
etc
]
You can use sets to remove the duplicates:
const vectors = [
{x: 6.869495194905539e-9, y: -0.11905603855848312, z: -0.3318425416946411},
{x: 6.869495194905539e-9, y: -0.11905603855848312, z: -0.3318425416946411},
{x: 6.869495194905539e-9, y: -0.11905603855848312, z: -0.3318425416946411},
{x: 0.06476999074220657, y: -0.11905603855848312, z: -0.3254662752151489},
{x: 0.06476999074220657, y: -0.11905603855848312, z: -0.3254662752151489},
{x: 0.06476999074220657, y: -0.11905603855848312, z: -0.3254662752151489},
{x: 0.06476999074220657, y: -0.11905603855848312, z: -0.3254662752151489},
{x: 0.12705090641975403, y: -0.11905603855848312, z: -0.306582510471344},
{x: 0.12705090641975403, y: -0.11905603855848312, z: -0.306582510471344},
{x: 0.12705090641975403, y: -0.11905603855848312, z: -0.306582510471344}
];
const arrayWithoutDuplicates = Array.from(
new Set(vectors.map(v => JSON.stringify(v))),
json => JSON.parse(json)
);
Nevermind, I did finally find an answer in another thread here.
var result = arr.reduce((unique, o) => {
if(!unique.some(obj => obj.x === o.x && obj.y === o.y && obj.z === o.z)) {
unique.push(o);
}
return unique;
},[]);
console.log(result);
Remove duplicate values from an array of objects in javascript
I have a data array like this
{x: 0, y: 7.9}
{x: 1, y: 7.5}
{x: 2, y: 7.0}
{x: 3, y: 7.4}
{x: 4, y: 7.3}
{x: 5, y: 7.2}
{x: 6, y: 7.5}
{x: 7, y: 7.6}
{x: 8, y: 7.7}
{x: 9, y: 7.2}
Based on this data, how can I find out the following y?
For example, I used a library to find out this data but how could I predict based on this data
the following data
eg for the next 30 indexes
now I have this
const cleanData = helpers.cleanData(this.data.datasets[0].data);
const ordersRegression = regression.linear(cleanData);
const regressionPoints = ordersRegression.points.map(([x, y]) => {
return {x, y};
});
this.data.datasets[1].data = regressionPoints;
But now I would like to do something with the data that I have to predict the following
It's possible ?
Is there a genuine formula?
This question already has answers here:
How to remove duplicates objects in array based on 2 properties?
(6 answers)
Closed 1 year ago.
I'm storing some coordinates in an array. It looks like this:
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}, {x: 180, y: 60}, {x: 180, y: 60}]
How can I filter this array so the objects are unique, meaning there are no duplicates of objects with same x and y value? Expected output should be:
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}]
I've seen some similar solutions, but they didn't really solve this problem.
I started with the following function
const output = Object.values(
coords.reduce( (c, e) => {
if (!c[e.x]) c[e.x] = e;
return c;
}, {})
but it only returns objects with different x values, so it just completely ommits y value.
One idea is to use a Set, map the x & y into a string, and then deserialize the Set to have unique x,y's..
eg..
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}, {x: 180, y: 60}, {x: 180, y: 60}];
const dedup = [...new Set(coords.map(m => `${m.x}:${m.y}`))].map(m => {
const [x,y] = m.split(':').map(n => n | 0);
return {x,y};
});
console.log(dedup);
We can use Array.reduce(),
along with a Map to get the required result.
We'd add each item to the map, using the concatenated x and y values as keys, then return the values() to get de-duplicated values.
This will have complexity of O(n), so it will be efficient for large arrays.
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}, {x: 180, y: 60}, {x: 180, y: 60}];
const dedup = [...coords.reduce((map, { x, y }) => {
return (map.set(`${x}-${y}`, { x, y }));
}, new Map()).values()];
console.log('De-duplicated:', dedup)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Or with a regular object:
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}, {x: 180, y: 60}, {x: 180, y: 60}];
const dedup = Object.values(coords.reduce((acc, { x, y }) => {
return { ...acc, [`${x}-${y}`]: { x, y }}
}, {}));
console.log('De-duplicated:', dedup)
.as-console-wrapper { max-height: 100% !important; top: 0; }
A pretty inefficient (O(n^2)), but flexible and straightforward solution: You first define a function that checks if two coordinates are equal. Then you filter all elements which have an equal element at a later position in the array.
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}, {x: 180, y: 60}, {x: 180, y: 60}]
const customUnique = (arr, isEqual) => {
// filter elements where an equal element exists at an earlier position
// thus the first element is kept
return arr.filter((a, i) => !arr.some((b, j) => i > j && isEqual(a, b)))
}
console.log(customUnique(coords, (a, b) => a.x === b.x && a.y === b.y))
You can use originalArray.reduce() with an array instead of an object, so you can make use of array.find.
const coords = [{x: 260, y: 60}, {x: 180, y: 0}, {x: 180, y: 240}, {x: 360, y: 120}, {x: 180, y: 60}, {x: 180, y: 60}, {x: 180, y: 60}]
console.log(
coords.reduce((arr, e) => {
if (!arr.find(item => item.x == e.x && item.y == e.y)) {
arr.push(e);
}
return arr;
}, [])
);
Yet another simple solution using a temporary array. However not the best as I could say:
const filteredCoords: any = [];
for(let coord of coords)
if (!filteredCoords.find((ele: { x: number; y: number; }) => ele.x == coord.x && ele.y == coord.y)){
filteredCoords.push(coord)
}
im looking for a function to add the value of the previous day to each next day.
I have following array:
{x: "8.9.2021", y: 0},
{x: "9.9.2021", y: 33},
{x: "10.9.2021", y: 0},
{x: "11.9.2021", y: 0},
{x: "12.9.2021", y: 0},
{x: "13.9.2021", y: 0},
{x: "14.9.2021", y: 0},
{x: "15.9.2021", y: 8},
{x: "16.9.2021", y: 0},
{x: "17.9.2021", y: 99},
{x: "18.9.2021", y: 0},
{x: "19.9.2021", y: 0},
{x: "20.9.2021", y: 113},
{x: "21.9.2021", y: 57},
{x: "22.9.2021", y: 16},
{x: "23.9.2021", y: 0},
...
And im looking for something like this:
{x: "8.9.2021", y: 0},
{x: "9.9.2021", y: 33},
{x: "10.9.2021", y: 33},
{x: "11.9.2021", y: 33},
{x: "12.9.2021", y: 33},
{x: "13.9.2021", y: 33},
{x: "14.9.2021", y: 33},
{x: "15.9.2021", y: 41},
{x: "16.9.2021", y: 41},
{x: "17.9.2021", y: 140},
{x: "18.9.2021", y: 140},
{x: "19.9.2021", y: 140},
{x: "20.9.2021", y: 253},
{x: "21.9.2021", y: 310},
{x: "22.9.2021", y: 326},
{x: "23.9.2021", y: 326},
...
That is what i tried but that froze my page
const add = (array) => {
let newArray= orders;
for (let i = 0; i < array.length; i++) {
newArray[i] = { x: orders[i].x, y: orders[i].y + orders[--i] && orders[--i].y, }; }
return newArray;
};
Didn't find any solutions yet. The solution should be as simple as possible.
You can iterate over the array, and add the values of y
const data = [{x: "8.9.2021", y: 0},
{x: "9.9.2021", y: 33},
{x: "10.9.2021", y: 0},
{x: "11.9.2021", y: 0},
{x: "12.9.2021", y: 0},
{x: "13.9.2021", y: 0},
{x: "14.9.2021", y: 0},
{x: "15.9.2021", y: 8},
{x: "16.9.2021", y: 0},
{x: "17.9.2021", y: 99},
{x: "18.9.2021", y: 0},
{x: "19.9.2021", y: 0},
{x: "20.9.2021", y: 113},
{x: "21.9.2021", y: 57},
{x: "22.9.2021", y: 16},
{x: "23.9.2021", y: 0}]
const incremented = []
data.forEach((el, index) => {
index === 0 ? incremented.push(el) :
incremented.push({...el, y: el.y + incremented[index-1].y})
})
console.log(incremented)
I have an array as follows:
var arr1 = [{x: 0, y: 0}, {x: 10, y: 10}, {x: 20, y: 20}, {x: 30, y: 30}, {x: 40, y: 40}]
arr1 represents the data in an infotable created by a user and I have sorted arr1 in ascending order of x using .sort.
arr1.sort(function(a, b){return a.x - b.x});
When the user changes the name of the values in the infotable (arr1) from x to z or creates a new infotable with different names, I have to modify my code to sort it again.
var arr1 = [{z: 0, y: 0}, {z: 10, y: 10}, {z: 20, y: 20}, {z: 30, y: 30}, {z: 40, y: 40}]
arr1.sort(function(a, b){return a.z - b.z});
Therefore, I want my sort function to be dynamic so that I do not have to change the code when the name of the values in the array is changed or when an infotable with new names is created. I hope I got my question across clearly, any help is greatly appreciated!
You could store the key to sort by in a variable and use that variable instead. Example:
var arr1 = [{z: 0, y: 0}, {z: 10, y: 10}, {z: 20, y: 20}, {z: 30, y: 30}, {z: 40, y: 40}]
let keyToSortBy = 'z'
arr1.sort(function(a, b){return a[keyToSortBy] - b[keyToSortBy]});
If you are a fan of lodash.
import _ from "lodash"
let key = 'z' // dynamic key
_.sortBy(arr1, key);
You need to figure out a way to dynamically tell your algorithm what's the field you need to sort by. One example would be including a property in each element with the name of the field to sort. Sample:
var arr1 = [{x: 0, y: 0, sort: 'x'}, {x: 10, y: 10, sort: 'x'}]
var arr1 = [{z: 0, y: 0, sort: 'z'}, {z: 10, y: 10, sort: 'z'}]
Then, your sort function would be the same:
var sortFunction = function(a, b){return a[a['sort']] - b[b['sort']]}
arr1.sort(sortFunction);
arr2.sort(sortFunction);
Your sample data doesn't show much difference with the value sorted by either key as the results are the same for either sort.
I changed your data slightly to show the differences using the FF console.log
The sort function could be condensed by calling a function instead of the inline defined logic.
`
Test Page
</style>
</head><body>
<script>
console.clear();
var arr1 = [{z: 0, y: 40}, {z: 10, y: 30}, {z: 20, y: 20}, {z: 30, y: 10}, {z: 40, y: 0}];
console.log('original');
console.log(arr1.toSource());
console.log();
let keyToSortBy = 'z'
arr1.sort(function(a, b){return a[keyToSortBy] - b[keyToSortBy]});
console.log('original sorted by ascending "z"');
console.log(arr1.toSource());
console.log();
keyToSortBy = 'y'
arr1.sort(function(a, b){return a[keyToSortBy] - b[keyToSortBy]});
console.log('original sorted by ascending "y"');
console.log(arr1.toSource());
console.log();
</script>
</body></html>
`
Make a function that returns a function:
var arr1 = [{z: 0, y: 0}, {z: 10, y: 10}, {z: 20, y: 20}, {z: 30, y: 30}, {z: 40, y: 40}]
const sortBy = (key) => (a, b) => a[key] - b[key];
arr1.sort(sortBy('z'));
console.log(arr1);
If you need, you may "encode" the key in the array as a property (not iteratable):
var arr1 = [{z: 0, y: 0}, {z: 10, y: 10}, {z: 20, y: 20}, {z: 30, y: 30}, {z: 40, y: 40}];
arr1.sortKey = 'z';
const sortBy = (key) => (a, b) => a[key] - b[key];
arr1.sort(sortBy(arr1.sortKey));
console.log(arr1);
And last, you may create your own sort function to ALL arrays in your program:
var arr1 = [{z: 0, y: 0}, {z: 10, y: 10}, {z: 20, y: 20}, {z: 30, y: 30}, {z: 40, y: 40}];
arr1.sortKey = 'z';
Array.prototype.mySort = function() {
this.sort((a, b) => a[this.sortKey] - b[this.sortKey]);
};
arr1.mySort();
console.log(arr1);
You can add a sortByKey to the Array prototype:
Array.prototype.sortByKey = function (key) {
return this.sort((a, b) => a[key] - b[key]);
};
const arr = [
{ x: 1, y: 100 },
{ x: 100, y: 5 },
{x: 3, y: 99 },
];
console.log(arr.sortByKey('x'));
console.log(arr.sortByKey('y'));
See the example below. Every time you make a change use xzSort.
function xzSort(array){
array.sort(function(a, b){
var A = 'x' in a ? 'x' : 'z';
var B = 'x' in b ? 'x' : 'z';
return a[A] - b[B];
});
return array;
}
var a = [{z:40, y:40}, {z:10, y:10}, {z:0, y:0}, {z:20, y:20}, {z:30, y:30}];
console.log(a); console.log(xzSort(a)); a[3] = {x:10, y:15}; console.log(xzSort(a));