Hey I need your help in respect of converting arrays in javascript. Please look on my output data:
Answers: {
'0': { '0': 'ans 1' },
'1': { '0': 'ans 11', '1': 'ans 22', '2': 'ans 33' }
}
correctAnswers: {
'1': { '0': true, '1': true }
}
And I would like if indexes doesn't match set false, so I expect following array:
convertArray = [[false], [true, true, false]]
For this task I use following function
var choiceBoolean = [];
for(corrAns in Answers){
let tempArr = [];
Object.keys(Answers[corrAns]).forEach(k =>
tempArr[k] = correctAnswers[corrAns][k] || false)
choiceBoolean.push(Array.apply(null, tempArr).map(Boolean))
}
Unfortunately I receive error TypeError: Cannot read property '0' of undefined
You could map the keys from answer with another mapped array from the inner keys by checking correct answers.
This solution works with a check if the correct answer exist and then it checks the inner key.
correct[k] && correct[k][l] || false
^^^^^^^^^^ check first if exists
^^^^^^^^^^^^^ take a truthy value
^^^^^ if not take false
var answers = { 0: { 0: 'ans 1' }, 1: { 0: 'ans 11', 1: 'ans 22', 2: 'ans 33' } },
correct = { 1: { 0: true, 1: true } },
result = Object
.keys(answers)
.map(k => Object.keys(answers[k]).map(l => correct[k] && correct[k][l] || false));
console.log(result);
Related
Hi i have an array of objects that i want to sort based on a boolean that one of the objects has. However normally there would be either true or false but in this case we also check on null values because sometimes the data has not been set and in that case we wanna show that it has yet to be set with an icon.
Here's an example of the array:
const arrayOfObjects = [
{
id: 69,
boolean: true,
name: 'foo',
},
{
id: 42,
boolean: false,
name: 'bar',
},
{
id: 666,
boolean: null,
name: 'foo',
},
{
id: 420,
boolean: false,
name: 'bar',
},
{
id: 2,
boolean: null,
name: 'foo',
},
{
id: 123,
boolean: true,
name: 'foo',
},
]
So what i tried first was:
arrayOfObjects.sort((a, b) => b.boolean - a.boolean);
This sets the objects that are true at the front but the objects with false or null are scattered.
Then i tried:
arrayOfObjects.sort((a, b, c) => (c.boolean - b.boolean) - a.boolean);
This just didn't work at all.
I couldn't really find a case that was similar enough to base a solution off of it so hopefully i can find it here.
If you like to use a custom sorting, you could take an object with the wanted sorting, like
const
order = { true: 1, null: 2, false: 3 };
data = [{ id: 69, boolean: true, name: 'foo' }, { id: 42, boolean: false, name: 'bar' }, { id: 666, boolean: null, name: 'foo' }, { id: 420, boolean: false, name: 'bar' }, { id: 2, boolean: null, name: 'foo' }, { id: 123, boolean: true, name: 'foo' }];
data.sort((a, b) => order[a.boolean] - order[b.boolean]);
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you have unknown values and want to move them to bottom, you could add another key with a large value, like
order = { true: 1, null: 2, false: 3, bottom: Number.MAX_VALUE };
Usage:
data.sort((a, b) =>
(order[a.boolean] || order.bottom) - (order[b.boolean] || order.bottom)
);
You can check for the null explicitly ...
let list = [{i: 0, boolean: true}, { i: 1, boolean: null}, { i:2, boolean: false}, { i: 4, boolean: true}]
function cpBoolWithNull(a,b) {
//if both are null return 0 to maintain a stable sort
//if only one is null return 0 or 1 depending on the value of the other
if (a.boolean === null) return b.boolean === null ? 0 : b.boolean ? 1 : -1;
if (b.boolean === null) return a.boolean ? -1 : 1;
//if both are different from null, sort true before false
return b.boolean - a.boolean
}
console.log(list.sort(cpBoolWithNull));
This will sort true ... null ... false If you need a differnt order, adjust the return values.
I think that you can have a type checker with JS with this simple script.
let array =[true, false, null];
function check(i){
if (array[i] != null||array[i]!=false){
if (array[i]!=null || array[i]!=true)document.write(" Array item"+" "+i+" "+"has the value of boolean false. ");
if (array[i]!=true||array[i]!=false)document.write(" Array item"+" "+i+" "+"has the value of boolean true. ");
if (array[i] != true || array[i] != false )document.write(" Array item"+" "+i+" "+"has the value of object null. ");
document.write("<br>")
}
}
check(0);
You can comment out the other text when it is not needed.
I'm trying to solve an algorithmic problem from codewars.
Given a function aliasGen(){} with an object { '0': 'Mike', '1': 'Millington' } as an argument, I need to extract the first letter of each value and match them to other data objects firstName = [{ A: 'Alpha', ...etc] && surname=[{ A: 'Analogue', B: 'Bomb',C: 'Catalyst', ...etc}] to generate a random alias.
firstname and surname are given and contain the "random names" to match from
var firstName = { A: 'Alpha', B: 'Beta', C: 'Cache', D: 'Data', E: 'Energy', ...etc}
var surname = { A: 'Analogue', B: 'Bomb', C: 'Catalyst', D: 'Discharge', E: 'Electron', ...etc}
Some of the test cases
Test.assertEquals(aliasGen("Mike", "Millington"), "Malware Mike");
Test.assertEquals(aliasGen("Fahima", "Tash"), "Function T-Rex");
Test.assertEquals(aliasGen("Daisy", "Petrovic"), "Data Payload");
Special Cases
If the first character of either of the names given to the function is not a letter from A - Z, you should return "Your name must start with a letter from A - Z."
Sometimes people might forget to capitalize the first letter of their name so your function should accommodate for these grammatical errors.
This is the kata just in case: codewars
I actually think I'm over engineering this. Right now I'm actually stuck on the Special Cases.
This is what I have now.
function aliasGen(){
// Code Here
// console.log(firstName)
// console.log(surname)
console.log(arguments) // { '0': 'Mike', '1': 'Millington' }
let propertyNames = Object.values(arguments)
console.log(propertyNames) // [ 'Mike', 'Millington' ]
var firstLetters = propertyNames.map(name => name[0])
console.log(firstLetters, 'firstLetters') [ 'M', 'M' ] 'firstLetters'
let lettersRegexp = /[A-Z]/;
if (firstLetters.map( letter => lettersRegexp.test(letter))) {
var firstNamePseudoObj = Object.keys(firstName)
.filter((key) => key.includes(firstLetters[0]))
.reduce((obj, key) => {
return Object.assign(obj, {
[key]: firstName[key]
});
}, {});
var lastNamePseudoObj = Object.keys(surname)
.filter((key) => key.includes(firstLetters[1]))
.reduce((obj, key) => {
return Object.assign(obj, {
[key]: surname[key]
});
}, {});
let arrayOfPseudos = [Object.values(firstNamePseudoObj), Object.values(lastNamePseudoObj)].map(arr => String(arr)).join(' ')
console.log(Object.values(firstNamePseudoObj), 'firstPseudo') // [ 'Malware' ] 'firstPseudo'
console.log(Object.values(lastNamePseudoObj), 'lastPseudo') [ 'Mike' ] 'lastPseudo'
console.log(arrayOfPseudos) Malware Mike
return arrayOfPseudos
} else {
return `Your name must start with a letter from A - Z.`
}
}
I fail the following test cases
Log
{ '0': 'Anuddanumbha', '1': '23200' }
[ 'Anuddanumbha', '23200' ]
[ 'A', '2' ] 'firstLetters'
false
[ 'Alpha' ] 'firstPseudo'
[] 'lastPseudo'
Alpha
Expected: 'Your name must start with a letter from A - Z.', instead got: 'Alpha '
---
Log
{ '0': '82ckt', '1': 'vuvmy' }
[ '82ckt', 'vuvmy' ]
[ '8', 'v' ] 'firstLetters'
false
[] 'firstPseudo'
[] 'lastPseudo'
---
Log
{ '0': 'di5io', '1': 'tudou' }
[ 'di5io', 'tudou' ]
[ 'd', 't' ] 'firstLetters'
false
[] 'firstPseudo'
[] 'lastPseudo'
Expected: 'Data T-Rex', instead got:
You can simply take the first character of values passed to you, and then you need to check if it is an alphabet or not.
function aliasGen(first, second) {
let firstNameChar = first[0].toUpperCase()
let lastNameChar = second[0].toUpperCase()
if (/[A-Z]/.test(lastNameChar)) {
return firstName[firstNameChar] + " " + surname[lastNameChar]
} else {
return "Your name must start with a letter from A - Z."
}
}
I have this simple function, and I am just trying to get the length of this array of objects. For instance I want to return 3 in that case below. I could use .length() but I want to explore more with the reduce method.
function getSum(data) {
const totalNum = data.reduce((sum, a) => sum + a.id, 0);
return totalNum
}
console.log(getSum([
{id: 'ddd6929eac', isComplete: true},
{id: 'a1dd9fbd0', isComplete: true},
{id: 'afa8ee064', isComplete: false}
]))
Thank you very much :)
Well the equivalent of data.length would be:
data.reduce(sum => sum + 1, 0);
But I don't see why you would do that unless you're trying to exclude blank values.
You could add one for each item in the array.
function getSum(data) {
return data.reduce((sum, a) => sum + 1, 0);
}
const
data = [{ id: 'ddd6929eac', isComplete: true }, { id: 'a1dd9fbd0', isComplete: true }, { id: 'afa8ee064', isComplete: false }];
console.log(getSum(data));
Simply you can just add index:
const totalNum = data.reduce((sum, a, index) => index+1);
This question already has answers here:
What is the difference between the `=` and `==` operators and what is `===`? (Single, double, and triple equals)
(5 answers)
Closed 1 year ago.
Say I have the following array of unnamed objects each of which is an array of named objects:
[{id: 123, name: 'Foo', code: 'ABC123', enabled: true},{id: 124, name: 'Bar', code: '123ABC', enabled: true}]
This data has been converted into an Array of objects from a API call response, so none of the named objects are defined. For instance I cant check the name of any object using something like:
for (let i = 0; i < resp.length; i++){
if(resp[i].name = key){do something}
}
(i.e the solution for the following question: Find a value in an array of objects in Javascript) because name is undefined for the objects in resp.
Is there a way for me to access that attribute on that object?
I would just use what your code, but slightly changed. The main error is that you're assigning a variable in your if statement (=) instead of comparing (==).
You also need to add a key and a matching word to the value of that key: resp[i][key] == match
const apiResponseArr = [{id: 123, name: 'Foo', code: 'ABC123', enabled: true},{id: 124, name: 'Bar', code: '123ABC', enabled: true}];
function find(resp, match, key) {
key = key || 'name';
for (let i = 0; i < resp.length; i++){
if(resp[i][key] == match) { return resp[i]; }
}
return 'not found';
}
console.log( find(apiResponseArr, 'Bar') ); // [object]
console.log( find(apiResponseArr, 'Zzz') ); // 'not found'
console.log( find(apiResponseArr, 'ABC123', 'code') ); // [object]
In your linked thread, you got a suggestion of writing it in an even shorter way:
const apiResponseArr = [{id: 123, name: 'Foo', code: 'ABC123', enabled: true},{id: 124, name: 'Bar', code: '123ABC', enabled: true}];
function find(resp, match, key = 'name') {
return resp.find(x => x[key] === match);
}
console.log( find(apiResponseArr, 'Bar') ); // [object]
console.log( find(apiResponseArr, 'Zzz') ); // undefined
console.log( find(apiResponseArr, 'ABC123', 'code') ); // [object]
I have an array of objects as shown below
[{
'0': 'RECORD_KEY',
'1': 'FIRST_TOUCH_DATE_TIME',
'2': 'ISA_SENDER_ID'
},
{
'0': '00208851228_1',
'1': '2020-02-19 13:08:20.0',
'2': 'CCA'
}, {
'0': ''
}
]
I want to remove the key and the last object which is null.
So the result would be -
[{
'0': 'RECORD_KEY',
'1': 'FIRST_TOUCH_DATE_TIME',
'2': 'ISA_SENDER_ID'
},
{
'0': '00208851228_1',
'1': '2020-02-19 13:08:20.0',
'2': 'CCA'
}
]
So each object would represent a row of data.
How can I possibly do this in node.js?
Your desird outcome is not valid JS. What you need is a nested array(array of arrays):
const arr =[
{
'0': 'RECORD_KEY',
'1': 'FIRST_TOUCH_DATE_TIME',
'2': 'ISA_SENDER_ID'
},
{
'0': '00208851228_1',
'1': '2020-02-19 13:08:20.0',
'2': 'CCA'
},
{ '0': '' }
]
const mainArr = []
for(let item of arr){
const subArr = []
for(let prop in item){
if(!item[prop]){
continue;
}
subArr.push(item[prop])
}
if(subArr.length){
mainArr.push(subArr)
}
}
One note: Please next time provide a formatted code snippet