Issue sorting by date with lodash - javascript

I'm trying to have a sorted list of items by data using lodash and vue moments, I'm using a computed property but for some reason this computed property named sortByUsedDate returns a number instead of a sorted array... it's returning 11 exactly.
This is my code:
sortByUsedDate: function(){
let sortedCodes = _.orderBy(this.modalPayload.discountcodes, (code) => {
return Vue.moment(code.usedDate).format('MDYYYY');
}, ['desc']);
let sortedWithoutUnused = _.remove(sortedCodes, function(code) {
return code.isBought === 1;
});
let unusedCodes = _.filter(this.modalPayload.discountcodes, function(code){
return code.isBought == 0;
});
let final = sortedWithoutUnused.push(unusedCodes);
return final;
}

.push returns the length of the array. You should just return the array without the assignment:
sortedWithoutUnused.push(unusedCodes);
return sortedWithoutUnused;
But if you're trying to combine two arrays, I don't think you want to use push anyway, you'll probably want to use ... or .concat instead:
return [...sortedWithoutUnused, ...unusedCodes];
Or
return sortedWithoutUnused.concat(unusedCodes);

Related

Nested array not returning expected value

I am trying to get access to individual values in an array within an array, I have the overall array, which has arrays in it, and then within that, I want to be able to access those values.
I would also likely assign each of those values to variables.
Essentially I am trying to iterate through what would become a grid of values (an array within an array) using JS.
1) I've tried accessing the value by pushing the row values into the array as a JSON string and then mapping it as array.map => row.map and then mapping it into individual elements
2) I've tried 'destructuring' the object but that did not seem to go anywhere either.
async function dataFormat(worksheet, rowNumber) {
csvWorkbook = workbook.csv.readFile("./uploads/uploadedFile.csv");
await csvWorkbook.then(async function(result) {
let restarts = 0;
let nullCounts = true;
let thermostatRows = [];
// you have to define THEN destructure the array
// const [serial,date,startDate,endDate,thing3,thing4,thing5] = firstTemps
worksheet.eachRow({ includeEmpty: true }, function(row, rowNumber) {
if (rowNumber > 6) {
Rows.push(`${JSON.stringify(row.values)}`);
}
});
console.log(thermostatRows[0])
})
};
Here is my function that returns the first row. If I put Rows[0][0] I get a letter.
here is the return of Rows[1]
[null,"2018-12 03T05:00:00.000Z","16:35:00","heat","heatOff", "hold","Home",70.1,70.1,69.8,43,33.8,0,0,15,15,null,69.8,43,1]
Which makes sense as it is the first row.
but logging Rows[0][0] gives me the first letter of null (first value in the array)
Lastly ,
[ '[null,"2018-12-02T05:00:00.000Z","23:25:00","heat","heatOff","auto","Home",72,72,72,47,41.3,0,0,0,0,null,72,47,0]',
'[null,"2018-12-03T05:00:00.000Z","16:35:00","heat","heatOff","hold","Home",70.1,70.1,69.8,43,33.8,0,0,15,15,null,69.8,43,1]',
'[null,"2018-12 03T05:00:00.000Z","16:40:00",null,null,null,null,null,null,null,null,33.8,0]'
Is the approximate log if I log Rows without anything else - to give you an idea of the whole situation.
edit: my function now looks like this, why would it return undefined?
if (rowNumber > 6) {
thermostatRows.push((row.values));
}
});
thermostatRows.map(thermostatRow => {
// let [date,time,SystemSetting,systemMode,calendarEvent,ProgramMode,coolSetTemp,HeatSetTemp,currentTemp,currentHumidity,outdoorTemp,windSpeed,coolStage1,HeatStage1,Fan,DMOffset,thermostatTemperature,thermostatHumidity,thermostatMotion] = thermostatSettings
console.log(date,time,SystemSetting)
})
})
};```
FINAL UPDATE
It works I figured out the undefined deal myself- try this. (this is with the excel.js library)
async function dataFormat(worksheet, rowNumber) {
csvWorkbook = workbook.csv.readFile("./uploads/uploadedFile.csv");
await csvWorkbook.then(async function(result) {
let restarts = 0;
let nullCounts = true;
let thermostatRows = [];
let thermostatSettings = []; // you have to define THEN destructure the array
// const [serial,date,startDate,endDate,thing3,thing4,thing5] = firstTemps
worksheet.eachRow({ includeEmpty: true }, function(row, rowNumber) {
if (rowNumber > 6) {
thermostatRows.push((row.values));
}
});
thermostatRows.map(thermostatRow => { [,date,time,SystemSetting,systemMode,calendarEvent,ProgramMode,coolSetTemp,HeatSetTemp,currentTemp,currentHumidity,outdoorTemp,windSpeed,coolStage1,HeatStage1,Fan,DMOffset,thermostatTemperature,thermostatHumidity,thermostatMotion] = thermostatRow
console.log(date,time,SystemSetting)
})
})
};
First, you need to be aware that Javascript arrays are zero-indexed. This means that to get the FIRST item, you use index 0. When you're calling Rows[1] you're actually getting the second item.
Second, you aren't creating a 2d array, you're creating a one dimensional array of strings.
Rows.push(`${JSON.stringify(row.values)}`);
This takes row.values and turns it into a string, interpolates it into another string, then pushes the final result into the array.
If you want an array inside the first array, which I assume row.values contains, do Rows.push(row.values);

How to use lodash _.find to return value even if iterating over numbers

so I have this function:
var res = _.find(table_campaign_boards().getAllPrimaryKeys(), (campaign_board_id,v) => {
var recCampaignTimeline = table_campaign_boards().getRec(campaign_board_id);
if (recCampaignTimeline.campaign_id == i_campaign_id) {
var board_id = recCampaignTimeline['board_id']
return table_boards().getRec(board_id);
}
});
And when a match is found, I get back the index since table_campaign_boards().getAllPrimaryKeys returns a list of numbers. How do I have _.find, find and stop on first value, and return the object found and not the index it found. Sure I can use for loop and break, but would rather use lodash as I get both key / value.
Thanks,
Sean

Get property value from an object inside of an array

I'm trying to grab class code property value from the object inside each array belonging to "class". (I'm aware my data is convoluted).
This is my student array:
student = [
{"class":[{
"code":"PSJ001",
"professor":"McHale",
"description":"course description"}]
},
{"class":[{
"code":"ENG303",
"professor":"Dench",
"description":"course description"}]
},
{"class":[{
"code":"SCI003",
"professor":"Biju",
"description":"course description"}]
}
]
What I'm trying to get is...
['PSJ001','ENG303','SCI003']
This is what I have...
let classCodes = [];
for (const i in student) {
classCodes = classCodes.concat(student[i].map(obj => {
return obj.code;
}));
}
What am I doing wrong here? (written in jsx)
You can use map() to get desired result
var student = [{"class":[{"code":"PSJ001","professor":"McHale","description":"course description"}]},{"class":[{"code":"ENG303","professor":"Dench","description":"course description"}]},{"class":[{"code":"SCI003","professor":"Biju","description":"course description"}]}];
var result = student.map(function(e) {
return e.class[0].code;
});
console.log(result)
Basically this will work reliable:
student.map(o => o.class.map(c => c.code)).reduce((obj, arr) => arr.push(...obj) && arr, []);
First we use .map() to get the classes, and inside we use .map() again to get the codes. This gives us a array of arrays. Then we use .reduce() to flatten that array.

Get the difference between two arrays of objects

I've got two arrays of objects, the difference between them is only that arrayAfter will have an element added:
var arrayBefore = [
{"name":"Alan","height":"171","weight":"66"},
{"name":"Ben","height":"182","weight":"90"}
];
var arrayAfter= [
{"name":"Alan","height":"171","weight":"66"},
{"name":"Ben","height":"182","weight":"90"},
{"name":"Chris","height":"163","weight":"71"}
];
"name" is always unique!
How can I find out which one is the element that has been added? I've tried ending up using nested for loops, but this seems overcomplicated.
I've also found the this nice idea:
var diff = $(arrayAfter).not(arrayBefore ).get();
However, that does not seem to work on arrays of objects straight ahead.
Is there some easy way to get the difference?
If only the name indicates uniqueness, you can do:
//Get a list of all the names in the before array
var beforeNames = arrayBefore.map(function(person) { return person.name });
//Filter the after array to only contain names not contained in the before array
var uniqueObjects = arrayAfter.filter(function(person) {
return beforeNames.indexOf(person.name) === -1;
});
console.log(uniqueObjects); //[{"name":"Chris","height":"163","weight":"71"}]
Demo: http://jsfiddle.net/tehgc8L5/
For a generic method you can combine Array.prototype.filter() with Array.prototype.reduce() which iterates over the object keys:
arrayAfter.filter(function(after) {
return !arrayBefore.reduce(function(found, before) {
if (!found) {
found = true;
for (key in before) {
if (before.hasOwnProperty(key)) {
found = found && (before[key] === after[key]);
}
}
}
return found;
}, false);
}); //[{name: "Chris", height: "163", weight: "71"}]
You can use Array.prototype.filter and filter out those elements in the previous array.
var differences = arrayAfter.filter(function(el) {
return arrayBefore.indexOf(el) === -1;
});
I believe jQuery will have nothing that will directly solve your problem here. Your problem being comparing objects for equality.
I am assuming that name is unique. If not, for this method you will need a unique identifier for data. If you absolute do not have one then you could concat all data to get one.
// first make a map of objects in before
var before = {};
arrayBefore.forEach(function(o){
before[o.name] = o;
});
// now we get the elements of after that do not exist in our hashmap
var result = arrayAfter.filter(function(o){
return !(o.name in before);
});
You can obviously wrap this up in a general function.

Return the index and array after reduced

I am playing with reduce method provided by mozilla. Underscore provides its own version which seems very similar. Reducing an array is very simple.
ArrayName.reduce(function(a,b) {
return a +b;
});
I use a very similar approach when sorting arrays as well. However, what I do not understand is how to return a list of calls. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce Provides a really cool table that shows how their method works. I set my array pretty much the same
var array = [1,2,3,100,55,88,2];
var sortArray= function(a,b) {
return a -b;
}
var sorted = array.sort(sortArray);
var reduced = sorted.reduce(function(previousValue,currentValue, index,array){
return previousValue + currentValue;
});
What I wanted to set up though was each call that was made. I figured that I could simply reference the index in the return value with a , at the end.
return previousValue + currentValue, index;
However, that only returns the index. I am trying to figure a way to get the value of each call. Does this approach allow you to get each call?
You don't need to use reduce for what you are doing. Try
function running_total(array) {
var sum = 0;
return array.map(function(elt) {
return sum += elt;
};
}
Reduce is about "boiling down" an array to a "single thing". In contrast, map is about "transforming" elements of the array. Your problem (as I understand it) is to transform each element of the array into the sum of itself and all the preceding elements. Therefore, conceptually, it's a map, not a reduce.
Using the , in the return statement will only return index due to the comma operator rule
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) {
console.log(previousValue+"--"+currentValue)
return previousValue + currentValue;
});
this will do want you want
You can create another array and store its value for each progress.
var array = [1,2,3,100,55,88,2];
var sortArray= function(a,b) {
return a -b;
}
var sorted = array.sort(sortArray);
var progress = [];
var reduced = sorted.reduce(function(previousValue,currentValue, index,array){
progress[index] = previousValue + currentValue;
return progress[index];
}, 0);
// ^^^^^
// give it a init value so it starts at first element.
console.log(progress);
However, as torazaburo says, as you expect to get an array, you should use .map which returns an array instead of .reduce.

Categories

Resources