Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
So i am trying to check if one object contains exactly another/ partial. For example, i want to check if { a: 1, b: 2, c: 2 } contains { a: 1, b: 2 }. But has to be in that order. If a is the first element and lines up, the b element will have to line up exactly afterwards. Plus is their anyway i could check there value? Order does matter.
//Here is my code currently:
function whatIsInAName(collection, source) {
var array = [];
var sourceNames = Object.getOwnPropertyNames(source);
for (var i = 0; i < collection.length; i++) {
var collectionNames = Object.getOwnPropertyNames(collection[i])
JSON.stringify(collectionNames).includes(JSON.stringify(sourceNames)) ? array.push(collection[i]) : null
}
return array
}
whatIsInAName([{ a: 1, b: 2 }, { a: 1 }, { a: 1, b: 2, c: 2 }], { a: 1, b: 2 });
Its a exact check but, only for the names. I wish it also compared the values.
It also isn't partially checking for the object in another. Like comaparing { a: 1, b: 2, c: 2 } to contain { a: 1, b: 2 }
Here was the challenge i was given --> https://www.freecodecamp.org/challenges/wherefore-art-thou
You coukd take the keys of the single object for comparing the values and use every for returning the result for filtering the array of objects.
Array#filter for getting parts of the array,
Object.keys for getting an array with own keys of the object,
Array#every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) for checking all keys and values,
in operator for check if the key exist in the object,
Identity/strict equality operator === for checking type and value of the operands.
function compare(array, object) {
return array.filter(function (o) {
return Object.keys(object).every(function (k) {
return k in o && object[k] === o[k];
});
});
}
console.log(compare([{ a: 1, b: 2 }, { a: 1 }, { a: 1, b: 2, c: 2 }], { a: 1, b: 2 }));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I was trying to guide you to figure out the problem on your own in the comments, but if you're just looking for a solution, here is how you can do this using basic JavaScript constructs (nothing fancy like Array#filter and Array#every).
It may be much longer than some other solutions, but it makes use of the basics of JavaScript:
function whatIsInAName(collection, source) {
var array = [];
var sourceNames = Object.getOwnPropertyNames(source);
// loop over each item in collection
for (var i = 0; i < collection.length; i++) {
var matchedProperties = 0;
// loop over each property in source
for (var j = 0; j < sourceNames.length; j++) {
// check whether the property is in collection[i] and
// whether the value matches
if (collection[i].hasOwnProperty(sourceNames[j]) &&
source[sourceNames[j]] === collection[i][sourceNames[j]]) {
matchedProperties += 1;
}
// add to array if all properties matched
if (matchedProperties === sourceNames.length) {
array.push(collection[i]);
}
}
}
return array
}
var result = whatIsInAName([{ a: 1, b: 2 }, { a: 1 }, { a: 1, b: 2, c: 2 }], { a: 1, b: 2 });
console.log(result);
Related
This question already has answers here:
How can we custom sort JavaScript object keys?
(3 answers)
Closed 24 days ago.
I have the following Javascript object:
let obj = {
a: 1,
b: 2,
d: 4
}
obj["c"] = 3
When I log this, the keys are in the order a, b, d, c. Is there a way to make it so that c is inserted between b and d?
One method is to create a new object with Object.fromEntries after sorting the entries of the original object.
let obj = {
a: 1,
b: 2,
d: 4
}
obj["c"] = 3;
let newObj = Object.fromEntries(Object.entries(obj).sort());
console.log(newObj);
Alternatively, just sort the keys before looping over them.
let obj = {
a: 1,
b: 2,
d: 4
}
obj["c"] = 3;
for (const key of Object.keys(obj).sort()) {
console.log(key, '=', obj[key]);
}
I have a simple question. I have two arrays A and B, I want to return array of object with mixing the two arrays.
For example:
let a = [ 1, 2 ]
let b = [ 3, 4 ]
Expected result:
const C = [
{
a: 1,
b: 3
},
{
a: 2,
b: 4
}
]
How can I do this?
I tried to forloop A then B and assign everytime but it didn't work.
You can use array map method on one of the array and use index to retrieve the element from the second array
let a = [1, 2]
let b = [3, 4];
let c = a.map((item, index) => {
return {
a: item,
b: b[index]
}
});
console.log(c)
Something like this should work:
let a = [1, 2];
let b = [3, 4];
// From #brk. This transforms each element of a to an object containing a's value and b's value
let c = a.map((item, index) => {
a: item,
b: b[index]
});
// Another way. Iterates through each element
for (let i = 0; i < a.length; i++) {
c[i].a = a[i];
c[i].b = b[i];
}
// Yet another. A combination of the first two.
for (let [index, item] of Object.entries(a)) {
c[index] = {
a: item,
b: b[index]
};
}
There's certainly a more elegant solution, but it evades me at the moment
I would love to "add/merge" (not sure how to call that) some objects in this manner:
obj1 = {
a: 1,
b: 1,
c: 1
}
obj2 = {
a: 1,
b: 1
}
obj1 + obj2 => { a: 2, b: 2, c: 1 }
Is there any way of achieving this? Tried, Object.assign(obj1, obj2) but It will not add properties like I need it to be done (it returns in { a: 1, b: 1, c: 1})
There isn't a built-in way to do it but you can enumerate the properties of one object and add their values to another.
const a = { a: 1, b: 1, c: 1 };
const b = { a: 1, b: 1 };
for(const prop in b) {
a[prop] = (prop in a ? a[prop] : 0) + b[prop];
}
console.log(a);
The prop in a check is so that we don't end up with NaN by adding undefined to the value in b.
You could use reduce to combine n number of objects like so:
const a = { a: 1, b: 1, c: 1 };
const b = { a: 1, b: 1 };
const c = { a: 1, c: 1 };
const result = [a, b, c].reduce((p, c) => {
for(const prop in c) {
p[prop] = (prop in p ? p[prop] : 0) + c[prop];
}
return p;
}, {});
console.log(result);
You didn't mention how you wanted to deal with properties in the prototype chain. You should know that for...in will enumerate properties in the prototype chain and prop in x will also examine the prototype chain. If your only want to enumerate the objects own properties then you could use Object.entries() to get its own properties or do a hasOwnProperty(...) check within the for...in and in place of the prop in x check. If you don't do any prototypal inheritance with your models then you may not care.
A quick answer:
let sum = {};
let keys = new Set(Object.keys(obj1))
Object.keys(obj2).map(x => keys = keys.add(x))
keys.forEach(x => {
let op1 = obj1[x] || 0;
let op2 = obj2[x] || 0;
sum[x] = op1 + op2;
})
Create an empty object:
var obj3 = {};
Use the spread operator to grab all the keys from both objects, then add them to the new object like so:
for(var i in {...obj1, ...obj2}) {
obj3[i] = (obj1[i] || 0) + (obj2[i] || 0);
}
var obj1 = {
a: 1,
b: 1,
c: 1
}
var obj2 = {
a: 1,
b: 2,
d: 3
}
var obj3 = {};
for(var i in {...obj1, ...obj2}) {
obj3[i] = (obj1[i] || 0) + (obj2[i] || 0);
}
console.log(obj3);
Who can explain how this for in loop works and why it's assign keys of object to array
var o = {
a: 1,
b: 2,
c: 3,
d: 4
};
var a = [],
i = 0;
for (a[i++] in o);
console.log(a);
Using a side effect when enumerating the object, and using an empty statement, each key is stored in the array a; first key in a[0], next in a[1] etc.
It is not necessary however since you could just use Object.keys(o)
var o = {
a: 1,
b: 2,
c: 3,
d: 4
};
var a = [],
i = 0;
for (a[i++] in o); // do nothing loop
console.log(a,Object.keys(o));
I have an array of objects that might look like this:
var arr = [{
a: 1,
b: 321,
c: 556,
d: 8
}, {
a: 1,
b: 22,
c: 21,
d: 8
}, {
a: 1,
b: 1,
c: 43,
d: 8
}, ];
and another list that could be:
var list = ['a', 'c', 'd'];
Since my list only has keys a, c, and d I want to get rid of all instances of the b key on my original array. All this procedure has to be dynamic though because There is no way for me to know what those keys might be prior to receiving them.
Is there a nice and clean way of doing this in JavaScript?
arr.forEach(function(element)
{
for(var key in element)
{
if(list.indexOf(key) === -1)
{
delete element[key];
}
}
});
Should be pretty self-explanatory.
If you don't want to modify the original array:
arr.map(function(element)
{
element = JSON.parse(JSON.stringify(element));
for(var key in element)
{
if(list.indexOf(key) === -1)
{
delete element[key];
}
}
return element;
});
Consider using the underscore.js library. It contains a reject method that should do the trick
reject _.reject(list, predicate, [context])
Returns the values in list without the elements that the truth test (predicate) passes. The opposite of filter.
var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [1, 3, 5]
Is that what you're looking for?
for(var i=0, i < arr.length; i++) {
if(arr[i].b) delete arr[i].b
}
// Update, a vanilla approach
var reject = [ "b" ];
for(var i=0, i < arr.length; i++) {
for(var j in arr[i]) {
if(reject.indexOf(j) != -1) delete arr[i][j];
}
}