This question already has answers here:
Why Array.indexOf doesn't find identical looking objects
(8 answers)
Closed 3 years ago.
Array.IndexOf() function behaves different for strings and objects.
stringBehaviour();
objectBehaviour();
function stringBehaviour() {
let s1 = "helmet";
let s2 = "trousers";
let collection = [];
collection.push(s1);
collection.push(s2);
console.info(collection.indexOf("trousers"));
};
function objectBehaviour() {
let obj1 = {item: "helmet"};
let obj2 = {item: "trousers"};
let collection = [];
collection.push(obj1);
collection.push(obj2);
console.info(collection.indexOf({item: "trousers"}));
};
what can i do to have indexOf() not looking for the same instance but for equality of the objects elements so that the function objectBehaviour() would return 1?
You could use findIndex instead and pass a function which compares objects by their properties.
stringBehaviour();
objectBehaviour();
function stringBehaviour() {
let s1 = "helmet";
let s2 = "trousers";
let collection = [];
collection.push(s1);
collection.push(s2);
console.info(collection.indexOf("trousers"));
};
function objectBehaviour() {
let obj1 = {item: "helmet"};
let obj2 = {item: "trousers"};
let collection = [];
collection.push(obj1);
collection.push(obj2);
console.info(collection.findIndex(el => isIdentical(el, { item: "trousers"})));
};
function isIdentical(current, given) {
return Object.keys(given).every((key) => current[key] === given[key]);
}
Related
This question already has answers here:
Merge keys array and values array into an object in JavaScript
(14 answers)
Closed 7 months ago.
consider this two arrays array y and array x i need to concatenates them but not after each other but be organised as in the form of array k
the concatenate method just output them after each other
let x=['name','age','id'];
let y=['kyle',50,5050];
let k= x.concat(y);
the output i get is
k=['name','age','id','kyle',50,5050]
so how to merge them to get this output array
let k=['name':'kyle','age':50,'id':5050]
This is possible, but not as an array. You need an object.
const x = ['name', 'age', 'id'];
const y = ['kyle', 50, '5050'];
const k = {};
x.forEach((element, index) => {
k[element] = y[index];
});
console.log(k);
In fact, the javascript array doesn't look like this. We can have an array of objects or array of arrays
let keys=['name','age','id'];
let values=['kyle',50,5050];
var array = keys.map((el, i) => {
return {[keys[i]]:values[i]}
}); // as array of objects
var array = keys.map((el, i) => {
return [keys[i], values[i]];
}); // as array of arrays
of if you want a single object you can use
let obj = {};
keys.forEach((element, index) => {
obj[element] = values[index];
});
This should work for you
Note: k is not an array, it's an object read about JavaScript object here
let x = ['name', 'age', 'id'];
let y = ['kyle', 50, 5050];
let k = {};
x.forEach((item, index) => {
k[item] = y[index];
});
console.log(k);
Simply with map:
let x = ['name', 'age', 'id'];
let y = ['kyle', 50, 5050];
k= x.map((prop, i) => [prop, y[i]]);
console.log(k);// [["name","kyle"],["age",50],["id",5050]]
This question already has answers here:
Object comparison in JavaScript [duplicate]
(10 answers)
How to determine equality for two JavaScript objects?
(82 answers)
Closed 3 years ago.
I have an array
let arr = []
I am inserting an object into it
let a = {name:"a", age: 20}
arr.push(a);
I am checking index with below with same object assigned to different variable
let b = {name:"a", age:20}
I tried
arr.indexOf(b);
I am getting -1 I expect 0.
Please guide me
JS does object comparison (and search) by reference, not by value. Hence: for foo == bar to be true, foo and bar must be the same object, not just an object with the same properties and values:
console.log({name:"a", age:20} == {name:"a", age:20});
Hence instead of indexOf, you need something like findIndex.
let arr = [];
let a = {name:"a", age: 20};
arr.push(a);
let b = {name:"a", age:20}
const index = arr.findIndex(item => item.name === b.name && item.age === b.age);
console.log(index);
This is because, objects are reference type, the variable a and b points to two different memory locations. Thus a != b
let a = {name:"a", age: 20};
let b = {name:"a", age:20}
console.log(a == b);
JavaScript can not compare objects by default. Use Array.findIndex instead:
let arr = []
let a = {name:"a", age: 20}
arr.push(a);
let b = {name:"a", age:20}
console.log(arr.findIndex(elem => elem.name == b.name && elem.age == b.age));
Yes because Js compare by using reference not by value
let arr = [];
let a = {
name: "a",
age: 20
};
arr.push(a);
let b = {
name: "a",
age: 20
};
console.log(arr.indexOf(b));
let arr = [];
let a = {
name: "a",
age: 20
};
arr.push(a);
let b = a
console.log(arr.indexOf(b));
This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 4 years ago.
Suppose I have an object
var obj = {
subObj : {
value : 1
}
};
Is there any way to get obj.subObj.value using a complex property-name string that goes to sub objects?
Example (that doesn't work)
var attr = "subObj.value";
return obj[attr];
No you can't.
You can split and loop over every attr.
var obj = {
subObj : {
value : 1
}
};
var attr = "subObj.value";
var result = obj;
attr.split('.').forEach((c) => result = result[c]);
console.log(result);
Or you can use reduce:
var obj = {
subObj : {
value : 1
}
};
var attr = "subObj.value";
var result = attr.split('.').reduce((a, c) => a[c], obj);
console.log(result);
There is no notation to do this in JavaScript but you could use something like this:
var obj = {
subObj : {
value : 1
}
};
var attr = "subObj.value";
var result = attr.split(".").reduce((a, c) => a[c], obj);
console.log(result)
My two arrays are:
const values = ['Master Clean', '45', '650']
const names = ['servicemenus.$.name', 'servicemenus.$.duration', 'servicemenus.$.cost']
The result should be like this:
{ 'servicemenus.$.name':'Master Clean', 'servicemenus.$.duration': '45', 'servicemenus.$.cost': 650}
Since I think that you know these two Arrays needs to be the same length at all time. This for loop could help you:
const values = ['Master Clean', '45', '650']
const names = ['servicemenus.$.name', 'servicemenus.$.duration', 'servicemenus.$.cost']
var obj = {}
for (var i = 0; i < names.length; i++) {
//or check with: if (values.length > i) { assignment }
obj[names[i]] = values[i];
}
console.log(obj);
Output will be this:
Object { servicemenus.$.name: "Master Clean", servicemenus.$.duration: "45", servicemenus.$.cost: "650" }
For completion, I found this Question could help you too: Merge two arrays into one Json object
You can work with the index of the array in a forEach to refer to the other and dynamically build the object keys:
const values = ['Master Clean', '45', '650']
const names = ['servicemenus.$.name', 'servicemenus.$.duration', 'servicemenus.$.cost']
let update = { };
names.forEach( (name,idx) => {
update[name] = values[idx];
});
And that gives you the result
From the assumption that the two arrays are always equal length, we can use one of them as the basis for a loop where we build the object:
let resultingObject = {};
names.forEach((name, i) => {
resultingObject[name] = values[i];
});
console.log(resultingObject);
You can reduce an array to a single value (object in your case). Reduce function accepts accumulator, current value and index which you can use to reference a value in the second array. Object.assign constructs an object with your keys/values.
const values = ['Master Clean', '45', '650'];
const names = ['servicemenus.$.name', 'servicemenus.$.duration', 'servicemenus.$.cost'];
const res = names.reduce((acc, cur, i) => Object.assign(acc, {[cur]: values[i]}), {});
console.log(res)
And with for in,loop through the object properties and assign it new object
var newobj = {};
for( var i in names){
newobj[names[i]] = values[i];
}
console.log(newobj);
var arrObj1 = [{a:1},{b:2}, {c:3}]
var arrObj2 = [{operator: LESS THAN}, {operator:GREATER THAN}, {operator:"NOT EQUAL"}]
so I want to merge obj at arrObj2[0] into obj at arrObj1[0], arrObj2[1] into obj at arrObj1[1] and so forth...
//resultArrObj = [{a:1, operator: LESS THAN}, {b:2, operator:"GREATER THAN}];
After (or while merging) i need to loop through each object and return a new obj which will have the properties(field, input, operator) and push into array.
field = key from arrObj1 (a, b, c)
input = value from arrObj1(1,2,3)
operator = "operator" from arrObj 2.
// var endResult = [{field:a, input:1, operator: LESS THAN}, {field:b, input:2, operator:GREATER THAN}];
thanks!!
I believe this does what you are looking for. It assumes that you know your data and doesn't do any error checking but just combines them the way that you asked.
var arrObj1 = [{a:1},{b:2}, {c:3}];
var arrObj2 = [{operator: "LESS THAN"}, {operator:"GREATER THAN"}, {operator:"NOT EQUAL"}];
var endResult = [];
var counter = 0;
var objNew = {};
arrObj1.forEach(function(fieldInput){
for ( field in fieldInput ){
objNew.field=field;
objNew.input=fieldInput[field];
objNew.operator=arrObj2[counter]['operator'];
counter++;
endResult.push(objNew);
objNew={};
};
})
// var endResult = [{field:a, input:1, operator: LESS THAN}, {field:b, input:2, operator:GREATER THAN}, {field:c, input:3, operator:NOT EQUAL}]
Let's break this problem into 2 steps:
1) Merging objects
2) Processing objects
We can write a generalized merging function:
if (!Object.prototype.extend) {
Object.prototype.extend = function (object) {
for (key in object) {
if (typeof object[key] === 'object' &&
typeof this[key] === 'object' &&
this.hasOwnProperty(key)) {
this[key].extend(object[key]);
} else {
this[key] = object[key];
}
}
return this;
};
};
The code above creates a method that all Objects share. It works like this:
var obj1 = { 'a': 7 },
obj2 = { 'b': 2 };
obj1.extend(obj2);
console.log(obj1); // { 'a': 7, 'b': 2 };
I usually wouldn't modify Objects like I have done with the .extend method, but it should be trivial to build something that does the same thing but has a different API. (for example, function extend (obj1, obj2) { do stuff.. and return extended object }
Anyways. That should solve the first part about merging objects.
The second part, processing this merged object, is simply using a for loop that iterates over the merged object, and pushes new objects into an array. It would look something like this:
for (var prop in mergedObject) {
var tempObject = {};
if (prop === 'operator') {
tempObject.operator = mergedObject.operator;
} else {
tempObject.field = prop;
tempObject.input = tempObject[prop];
}
endResult.push(tempObject);
}
Hopefully this helps you.