Reputation: 495
The array looks like:
var test = [
{
Time: new Date(1000),
psi:100.0
},
{
Time: new Date(1000),
psi:200.0
},
{
Time: new Date(2000),
psi:200.0
}
]
The function looks like (the function was copied from some online resource, couldn't find the exact reference.)
function uniqTimetable(nums){
console.log(nums); //log#1
var length = nums.length;
var count = 0;
for (var i =0; i< length-1; i++){
if (nums[count].Time.getTime() !== nums[i+1].Time.getTime()){
count ++;
nums[count] = nums[i+1];
}
}
nums.length = count + 1;
console.log(nums); // log #2
}
uniqTimetable(test);
console.log(test);// log #3
Are there any problems of
copy one object to the other array member by this linenums[count] = nums[i+1]
rescale the array length by this linenums.length = count + 1
?
With electron/node.js, the output looks a bit weird.
In log#1, it shows the array length is 2 instead of 3. Something seems wrong with the function. Any suggestions welcome.
Thanks in advance.
Upvotes: 0
Views: 62
Reputation: 28196
I like @Akin's answer! But unfortunately the .indexOf()
function does not work for Date objects with the same value, since each object is still considered to be different and the .indexOf()
function will always find the index of the Date object itself and never another "copy". To overcome this I convert the Date object back to milliseconds before collecting the values in an array (tst
). I do this with myArr.map(mapObj => mapObj[prop].getTime())
before I go into the .filter
function.
As the .getTime()
method will only work for Date objects it does not make sense to keep the property prop
as an argument. Instead I hardcoded the .Time
property into the code.
Edit:
By coercing a numerical data type with a unary operator +
for the .Time
property I can leave out the .getTime()
method which will be applied implicitly.
var test = [{Time: new Date(1000), psi:100.0},
{Time: new Date(1000), psi:200.0},
{Time: new Date(2000), psi:200.0}];
function Cars10m_remDups(myArr) {
let tst=myArr.map(o=>+o.Time);
return myArr.filter((o, i)=>tst.indexOf(+o.Time)===i);
}
// for comparison: --> will list all three objects!
function Akin_remDups(myArr, prop) {
return myArr.filter((obj, pos, arr) => {
return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos;
});
}
// Zero's one-liner works too, here: my shortened version
const Zero_remDups = myArr => myArr.filter(({Time}, i, array) =>
!array.find((item, j) => +item.Time-Time==0&&i>j));
// also: with "i>j" I pick the first unique (Zero chose the last)
console.log('Cars10m:',Cars10m_remDups(test));
console.log('Akin:',Akin_remDups(test,"Time"));
console.log('Zero:',Zero_remDups(test));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 25322
If I understood the problem, you can solve it in one line function:
const test = [{
Time: new Date(1000),
psi: 100.0
},
{
Time: new Date(1000),
psi: 200.0
},
{
Time: new Date(2000),
psi: 200.0
}
]
const unique = test.filter(({Time}, i, array) =>
!array.find((item, j) => item.Time.getTime() === Time.getTime() && j > i));
console.log(unique);
(I assumed psi
is not relevant)
It uses find and filter array's methods.
Upvotes: 2
Reputation: 1176
function removeDuplicates(myArr, prop) {
return myArr.filter((obj, pos, arr) => {
return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos;
});
}
removeDuplicates(test,"Time")
Using the filter function of javascript, to return the List of only unique elements.
Upvotes: 1