Assert sorted array of objects [duplicate] - javascript

This question already has an answer here:
Map and Sort in one iteration in Javascript?
(1 answer)
Closed 4 years ago.
I'm doing unit testing using javascript testing framework (mocha, chai, etc). How can I assert my array of objects using its name?
I can successfully sort this using localeCompare but I'm not getting what I wanted on my test. It just returns 1 or -1.
Here's my a sample of what I want to sort.
var Stuffs = [
{ name: "PWE", address: "1234567890" },
{ name: "NSA", address: "1234567890" },
{ name: "AVE", address: "1234567890" },
{ name: "QRE", address: "1234567890" },
]
How can I assert this to ["AVE", "NSA", "PWE", "QRE"] ?

To get your desired Array, you can use:
Stuffs.map(({ name }) => name).sort();

You could also use reduce() method of array and then sort().
DEMO
var Stuffs = [{ name: "PWE", address: "1234567890" },
{ name: "NSA", address: "1234567890" },
{ name: "AVE", address: "1234567890" },
{ name: "QRE", address: "1234567890" }];
let sortedArr = Stuffs.reduce((r,{name})=>r.concat(name),[]).sort((a,b)=>a.localeCompare(b));
console.log(sortedArr);

Using chai
assert.deepInclude(Stuffs, {name: "AVE"});
assert.deepInclude(Stuffs, {name: "NSA"});
assert.deepInclude(Stuffs, {name: "QRE"});
assert.deepInclude(Stuffs, {name: "PWE"});
Edit: I may have misunderstood it to mean, how can assert that the array has those values.

First you would need a sorted array to compare it to. The original array needs to be cloned (shallow is fine for this) since sort will modify the array it is called on. Using from to generate the clone, we can then alphabetically sort the new array to get the desired order.
const sortedStuffs = Array.from(stuffs).sort(({name: a}, {name: b}) => a.localeCompare(b));
Finally using every, we can compare the names for each element to see if they match. As soon as one fails, the returned value will be false
stuffs.every(({name}, i) => name === sortedStuffs[i].name);
Full working example:
const stuffs = [
{name: "PWE", address: "1234567890"},
{name: "NSA", address: "1234567890"},
{name: "AVE", address: "1234567890"},
{name: "QRE", address: "1234567890"}
];
const sortedStuffs = Array.from(stuffs).sort(({name: a}, {name: b}) => a.localeCompare(b));
const isSorted = stuffs.every(({name}, i) => name === sortedStuffs[i].name);
console.log(isSorted);

Related

How can I update some array entries to have multiple values?

I have an array as such:
arr = {
name: 1,
address: 1,
phone: 2,
email: 5,
};
I want to be able to add further information to this array, eg:
arr = {
name: 1 true,
address: 1 false,
phone: 2 true,
email: 5 true,
};
I've tried a few different things like:
arr.email[2] = true;
With no results (or errors).
Is there a way to do this? Or a better way of handling this issue?
I'm not entirely certain what you're going for here since you mention wanting an array ([]) but what you've shown in your question is an object ({}), but if I'm reading right you can accomplish this with an object where each key holds an array of values. That would look like:
const obj = {
name: [1],
address: [1],
phone: [2],
email: [5],
};
obj.email.push(true);
obj.email.push("whatever");
console.log(obj)
console.log(obj.email[1])
console.log(obj.email[2])
So obj is an object, but name, address, phone, and email are all arrays which you can extend as needed with array methods.
Original data structure doesn't allow you to add data the way you want. So you have to create the object with needed data structure at first. After this the original data should be moved to the new object and only after this you can add some new data.
newObj.name.push(origObj.name,true,"something1","something2");
newObj.address.push(origObj.address,false);
newObj.phone.push(origObj.phone,true);
newObj.email.push(origObj.email,true);
output
{
"name":[1,true,"something1","something2"],
"address":[1,false],
"phone":[2,true],
"email":[5,true]
}
original object
var origObj = {
name: 1,
address: 1,
phone: 2,
email: 5
};
new object
var newObj = {
name: [],
address: [],
phone:[],
email: []
};
You would need to assign a variable to your array and call a function...that way, each element could be classified (boolean, string, integer, etc.) For example,
const fruit = ['banana', 'apple', 'pear'];
console.log(fruit);

creating a unique array in Javascript

Im having trouble creating an array that contains unique subset of a larger array, please help!
Original Array allMembers (6)[{},{},{},{},{},{}]
allMembers Payload: 0:{id:1, name: Alex} 1:{id:2, name: James} 2:{id:3, name: Bob} 3:{id:4, name: lara} 4:{id:5, name: Dan} 5:{id:6, name: Jes}
Second array uniqueMembers (3)[{},{},{}]
uniqueMembers Payload: 0:{id:1, name: Alex} 1:{id:2, name: James} 2:{id:3, name: Bob}`
what I'm looking for is to find the users that are in allMembers but not in uniqueMembers
so my desired new array output would be the following array resultArray
resultArray (3)[{},{},{}]
resultArray Payload: 0:{id:4, name: lara} 1:{id:5, name: Dan} 2:{id:6, name: Jes}
My attempt
for(let m=0; m<allMembers.length;m++)
{
console.log('Testing include statement', uniqueMembers.includes(allMembers[m])) //output always false
if(uniqueMembers.includes(allMembers[m]))
{
console.log('ITS ALREADY IN: ', allMembers[m])
}else{
this.setState((prevState) => ({
resultArray: [...prevState.resultArray, allMembers[m]]
}));
console.log('ITS NOT IN: ', allMembers[m])
}
}// resultArray ends up the same as allMembers :(
Any feedback on how I can get the desired resultArray values would be appreciated!
Build an associative array to efficiently lookup if a member should be filtered out.
lookup = {}
for (const um uniqueMembers)
lookup[um.id] = 1;
resultArray = allMembers.filter( mem => !lookup.hasOwnProperty(mem) );
Two solutions posted after this one suggested using filter and some. Those solutions are O(N2). This one is should be O(N), which is way better.
If your unique array is very huge as well, convert unique array to one set first, it will save time to loop the unique array to check the match.
Then uses Array.filter to get the not in unique elements.
let all = [{id:1, name: 'Alex'}, {id:2, name: 'James'},{id:3, name: 'Bob'},{id:4, name: 'lara'},{id:5, name: 'Dan'} ,{id:6, name: 'Jes'}]
let unique = [{id:2, name: 'James'},{id:3, name: 'Bob'}]
function getNotInUnique(src, target) {
let uniqueSet = new Set(target.map(member => member.id))
return src.filter(member => !uniqueSet.has(member.id))
}
console.log(getNotInUnique(all, unique))
You can use filter along with some.
const allMembers = [
{id:1, name: 'Alex'},{id:2, name: 'James'},{id:3, name: 'Bob'}, {id:4, name: 'lara'}, {id:5, name: 'Dan'}, {id:6, name: 'Jes'}
];
const uniqueMembers = [
{id:1, name: 'Alex'},{id:2, name: 'James'},{id:3, name: 'Bob'}
];
const res = allMembers.filter(m => !uniqueMembers.some(({id})=>m.id===id));
console.log(res);

How to, with a one-lined solution, can I reduce an object containing arrays of arrays of objects to the inner objects? [duplicate]

This question already has answers here:
Why no Array.prototype.flatMap in javascript?
(8 answers)
Closed 3 years ago.
I have the following object structure:
regions: [
{
name: reg1,
subregions: [
{name: subreg11},
{name: subreg12}
]
},
{
name: reg2,
subregions: [
{name: subreg21},
{name: subreg22}
]
}
]
What I'd like, is to extract an array of the subregions, like so:
[{name: subreg11}, {name: subreg12}, {name: subreg21}, {name: subreg22}]
...and I'd like to do that with a one-line array.prototype-function, like .filter, .map, .forEach etc.
I've managed to do it in three lines like this (including the return-statement, which I'd like to have in the one-liner):
let subregions = []
regions.forEach(reg => reg.subregions.forEach(subregion => subregions.push(subregion)))
return locs
Does anyone know how I could do this?
EDIT July 2020: I see the question has been marked as a duplicate by #nina-sholz, but I don't believe this is true. The linked question asks "Why no Array.prototype.flatMap in javascript?", while my question was a description of a way to solve a problem. I didn't request the flatMap function specifically, and marking this as a duplicate simply says "you should have intuitively known that Array.prototype.flatMap was the thing you were looking for".
flatMap and extract the subregions property:
const regions = [
{
name: 'reg1',
subregions: [
{name: 'subreg11'},
{name: 'subreg12'}
]
},
{
name: 'reg2',
subregions: [
{name: 'subreg21'},
{name: 'subreg22'}
]
}
];
const output = regions.flatMap(({ subregions }) => subregions);
console.log(output);
You can also use reduce:
const regions = [
{
name: 'reg1',
subregions: [
{name: 'subreg11'},
{name: 'subreg12'}
]
},
{
name: 'reg2',
subregions: [
{name: 'subreg21'},
{name: 'subreg22'}
]
}
];
const output = regions.reduce((a, { subregions }) => a.concat(subregions), []);
console.log(output);
Pretty much any Javascript code can be reduced into a single line, but it won't necessarily be readable.
You can use map and flat
const regions = [{name: 'reg1',subregions: [{name: 'subreg11'},{name: 'subreg12'}]},{name: 'reg2', subregions: [{name: 'subreg21'},{name: 'subreg22'}]}];
const output = regions.map(({ subregions }) => subregions).flat();
console.log(output);

How to check if array of object contains a string [duplicate]

This question already has answers here:
How to determine if Javascript array contains an object with an attribute that equals a given value?
(27 answers)
Closed 3 years ago.
let's say I have an array of objects:
let arr = [
{
name: 'Jack',
id: 1
},
{
name: 'Gabriel',
id: 2
},
{
name: 'John',
id: 3
}
]
I need to check whether that array includes the name 'Jack' for example using:
if (arr.includes('Jack')) {
// don't add name to arr
} else {
// push name into the arr
}
but arr.includes('Jack') returns false, how can I check if an array of objects includes the name?
Since you need to check the object property value in the array, you can try with Array​.prototype​.some():
The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value.
let arr = [
{
name: 'Jack',
id: 1
},
{
name: 'Gabriel',
id: 2
},
{
name: 'John',
id: 3
}
]
var r = arr.some(i => i.name.includes('Jack'));
console.log(r);

Lodash orderBy returning empty array

I am trying to order an array with Objects in ascending order using lodash.orderBy npm module.
this is the example object I am using
var obj = [{ user: 'me', score: 100}, { user: 'you', score: 55}, { user: 'someone', score: 555 }]
Once I have that object, I pass it through as the first parameter and specify which key to orderBy.
let sort = orderBy(obj, 'score')
But this returns an empty array, is there something I am doing wrong ? based on the documentation this is correct: https://lodash.com/docs/4.17.4#orderBy
This may be an issue with the asynchronous call and saying the index of the Array is 0.
EDIT:
It seems as if you are not actually calling orderBy() on the lodash object. Try the following code:
JS
const _ = require('lodash');
var obj = [[{
user: 'me',
score: 100
},{
user: 'you',
score: 55
},{
user: 'someone',
score: 555
}]]
var data = obj[0];
let sort = _.orderBy(data, 'score');
console.log(sort);
Created a new variable data and assign it the value of obj[0] effectively assigning it the array. Lodash can then order the data as expected.
Console Output (score in ascending order by default)
[ { user: 'you', score: 55 },
{ user: 'me', score: 100 },
{ user: 'someone', score: 555 } ]
Possible solution for your code
let obj = this.state.items;
let data = obj[0];
let sort = lodash.orderBy(data, 'score');
console.log(sort);

Categories

Resources