Find object index from array - javascript

I'm trying to find out selected object index from array
But it always return -1 don't know why?
Here is I'm trying to do
I have following array in which their are multiple objects
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}]
And here is my another array that are selected by user
var dList = [{
"name": "abc",
"age": 25,
"school": "xyz pqr",
"isChecked": true
}]
Now I want to find out selected object index from data array and remove this object from that array
if (dList.length > 0) {
for (let i=0; i<dList.length; i++){
delete dList[i]['isChecked']
console.log(dList[i])
console.log(data[0])
console.log(dList[i] == data[0])
let index = data.indexOf(dList[i]);
console.log(index)
data.splice(index, 1);
}
}

Here is just a simple implementation:
if (dList.length > 0) {
for (let i=0; i<dList.length; i++) {
delete dList[i]['isChecked']
console.log(dList[i])
console.log(data[0])
console.log(JSON.stringify(dList[i]) === JSON.stringify(data[0]))
let index = data.findIndex(()=>dList[i]);
console.log(index)
data.splice(index, 1);
}
}
Comparing the objects can be done by just converting it into string using JSON.stringify(ObjectName).
Second instead of using indexOf use findIndex.
Here is the main difference between indexOf and findIndex.

You can only compare two primitive types only so you will not be able to get the index of the object by comparing it.
You should instead compare some primary key which will be unique for each object inside the array.
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}];
var index = data.findIndex(x => x.name=="abc2");
console.log(index);

this is going to meet your demand, a more universal version,if you got unique id,that is going to be the best choice:
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}
];
var dList = [{
"name": "abc",
"age": 25,
"school": "xyz pqr",
"isChecked": true
}];
dList.forEach(function(obj) {
delete obj.isChecked;
data.splice(data.findIndex((o) => {
return Object.getOwnPropertyNames(obj).every(p => obj[p] === o[p]);
}), 1);
});
console.log(data);
another way:
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}
];
var dList = [{
"name": "abc",
"age": 25,
"school": "xyz pqr",
"isChecked": true
}];
dList.forEach(function(obj) {
delete obj.isChecked;
data.splice(data.findIndex((o) => o.name === obj.name && o.age === obj.age && o.school === obj.school && o.school === obj.school), 1);
});
console.log(data);
unrecommended way:
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}
];
var dList = [{
"name": "abc",
"age": 25,
"school": "xyz pqr",
"isChecked": true
}];
dList.forEach(function(obj) {
delete obj.isChecked;
data.splice(data.findIndex((o) => JSON.stringify(o) === JSON.stringify(obj)), 1);
});
console.log(data);

You can use this also
var data = [{
"name": "abc",
"age": 25,
"school": "xyz pqr"
},
{
"name": "abc1",
"age": 26,
"school": "xyz pqr"
},
{
"name": "abc2",
"age": 27,
"school": "xyz pqr"
}];
var dList = [{
"name": "abc",
"age": 25,
"school": "xyz pqr",
"isChecked": true
}]
console.log(data.map(function(d){
return d.name;
}).indexOf(dList[0].name));

You cannot compare two Object Notations(JSON). To compare two JSONs you need to first stringify the object, then JavaScript can compare the two objects for you.
Here is a simple code for you to get what you desire.
if (dList.length > 0) {
for(var i=0; i<data.length; i++){
for(var j=0; j<dList.length; j++){
delete dList[j]['isChecked'];
if(JSON.stringify(data[i]) === JSON.stringify(dList[j])){
let index = data.indexOf(data[i]);//Gets the index of the array
data.splice(index, 1);
console.log(data);
}else{
console.log('Data Not Matched in Array');
}
}
}
}

There is no generic means to determine that an object is equal to another in the sense. Please see Equality comparisons for more information.
You can find and remove objects like below:
Array.prototype.remove = function(elem) {
var indexElement = this.findIndex(el => el.name === elem.name);
console.log(indexElement);
if (indexElement != -1)
this.splice(indexElement, 1);
return this;
};
data.remove(dList[0]);
console.log(data);
Online demo (jsFiddle)

var result= data.filter((item, i, self) => {
if (item.name === 'abc2') {
return { itemIndex: i, obj: item }
}
});
var output = result.map(r => { console.log(r.itemIndex) })
console.log(output);
This will return all objects in which name is abc2. findIndex array method will always return 1 index that might not be the case as people can have the same name.

Related

Object not replacing using spread operator

I want to replace existing object with new updated fields using spread operator. But I am not getting the correct result.
Below are my two objects.
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
I can do it with .map. Below is my code.
let result = obj1.map(item => {
if (item.id === newObj.id) {
return {...item, ...newObj};
}
return item;
});
But I do not want to run the loop and want to acheive by spread operator only.
Example for spread. Which is not working. It's not replacing the object. Instead creating one more.
[...obj1, newObj];
Can someone help me?
JSBIN CODE SNIPPET
Spread syntax doesn't replace the object within array like you used it. Using map is the simplest and understandable way. However if you want to use spread syntax you would first need to find the index to be replaced and then use slice on array
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
const idx = obj1.findIndex(item => item.id === newObj.id);
obj1 = [...obj1.slice(0, idx), newObj, ...obj1.slice(idx + 1)];
console.log(obj1);
Use Object.assign
The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
Object.assign(obj1[2], newObj);
console.log(obj1)
Using .find() to get the target obj
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
const targetObj = obj1.find(obj => obj.id === newObj.id)
Object.assign(targetObj, newObj);
console.log(obj1)
you should normalize your data by id this way:
obj1 = {
1: {
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
2: {
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
3: {
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
}
newObj = {
3: {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
}
this way you can use spread operator:
{ ...obj1, ...newObj }
in order to normalize you can use the reduce func this way:
const normalized = obj1.reduce((result, obj) => ({ ...result, [obj.id]: obj }), {})
Spread operator is magic but it won't do whatever you want, you will have to loop over and replace the object. Instead of doing a map(), I would prefer find(). The use Object.assign() to achieve what you want.
let obj1 = [
{
"id": 1,
"name": "Michel",
"age": 34,
"email": "michel#gmail.com"
},
{
"id": 2,
"name": "Abby",
"age": 40,
"email": "abby#gmail.com"
},
{
"id": 3,
"name": "Gary",
"age": 40,
"email": "abby#gmail.com"
}
]
let newObj = {
"id": 3,
"name": "Gary",
"age": 23,
"email": "gary#gmail.com"
}
let foundOb = obj1.find(e => e.id === newObj.id);
Object.assign(foundOb, newObj)
console.log(obj1)
You cannot use spread syntax in that way. One solution would be to find index of the object you want to replace by id property and then you could use spread syntax with slice method to create new array with replaced object.
let obj1 = [{"id":1,"name":"Michel","age":34,"email":"michel#gmail.com"},{"id":2,"name":"Abby","age":40,"email":"abby#gmail.com"},{"id":3,"name":"Gary","age":40,"email":"abby#gmail.com"}]
let newObj = {"id":3,"name":"Gary","age":23,"email":"gary#gmail.com"}
const index = obj1.findIndex(({id}) => id == newObj.id)
const result = [...obj1.slice(0, index), newObj, ...obj1.slice(index + 1)]
console.log(result)
I would do something like:
updatedObj = [obj1.map((entry) => entry.id !== newObj.id), newObj]
This would give me the updated object with minimal syntax

Adding key in an array by finding a value AngularJS

I am trying to add an extra key in a JSON array by searching any key value.
Example JSON:-
[
{
"$id": "2025",
"ID": 41,
"Name": "APPLE"
},
{
"$id": "2026",
"ID": 45,
"Name": "MANGO"
},
{
"$id": "2027",
"ID": 48,
"Name": "GUAVA"
}
]
Suppose I have to add a new key pair example "Price": 50 after "Name": "MANGO" or by finding ID ID": 45. So my expected new JSON will be :-
[
{
"$id": "2025",
"ID": 41,
"Name": "APPLE"
},
{
"$id": "2026",
"ID": 45,
"Name": "MANGO",
"Price": 50
},
{
"$id": "2027",
"ID": 48,
"Name": "GUAVA"
}
]
It must add on the object related to matched search key.
So, I am not able to find out any function related to the issue.
You can run a loop and check the condition and then add a property to an object. Here is a running code snippet. You can read here more about JavaScript Objects
var myarray = [
{
"$id": "2025",
"ID": 41,
"Name": "APPLE"
},
{
"$id": "2026",
"ID": 45,
"Name": "MANGO"
},
{
"$id": "2027",
"ID": 48,
"Name": "GUAVA"
}
]
for(var i=0;i<myarray.length;i++){
if(myarray[i].$id === "2025" || myarray[i].Name === "APPLE"){
var data = myarray[i];
data.price = 50
}
}
console.log(myarray)
You can use array#find to compare the ID. Then based that you can add Price key to the object.
let arr = [ { "$id": "2025", "ID": 41, "Name": "APPLE" }, { "$id": "2026", "ID": 45, "Name": "MANGO" }, { "$id": "2027", "ID": 48, "Name": "GUAVA" } ],
id = 45,
obj = arr.find(({ID}) => ID === id);
if(obj);
obj.Price = 50;
console.log(arr);
You can try with:
data.find(item => item.ID === 45).price = 50;
To cover the case if item is not available:
(data.find(item => item.ID === 45) || {}).price = 50;

Object is not been read node.js

I have and object db_parsed
when I run console.log(JSON.stringify(db_parsed, null, 4))
the result is:
{
"data": [
[
{
"name": "Me",
"age": 23,
"sex": "M"
},
{
"name": "Wonderwoman",
"age": 22,
"sex": "F"
}
],
[
{
"name": "ALbert The Man",
"age": 22,
"sex": "M"
}
],
[
{
"name": "Leonard Johnson",
"age": 23,
"sex": "M"
}
]
]
}
but when I run console.log(db_parsed.data.filter(obj => obj.age === 22))
the result is []
Why? What am i missing? How do I fix this?
db_parsed.data is an array containing arrays.
That second level of arrays contains objects.
Your filter code is trying to treat those objects and being directly inside db_parsed.data instead of inside db_parsed.data[0], db_parsed.data[1] and db_parsed.data[2].
You could use reduce to concatenate all the second level of arrays into one, and then filter on that.
var db_parsed = {
"data": [
[{
"name": "Me",
"age": 23,
"sex": "M"
},
{
"name": "Wonderwoman",
"age": 22,
"sex": "F"
}
],
[{
"name": "ALbert The Man",
"age": 22,
"sex": "M"
}],
[{
"name": "Leonard Johnson",
"age": 23,
"sex": "M"
}]
]
};
console.log(db_parsed.data.reduce((a,b) => a.concat(b), []).filter(obj => obj.age === 22))
You can do [].concat.apply([], db_parsed.data) and than filter the array of objects:
const db_parsed = {"data": [[{"name": "Me","age": 23,"sex": "M"},{"name": "Wonderwoman","age": 22,"sex": "F"}],[{"name": "ALbert The Man","age": 22,"sex": "M"}],[{"name": "Leonard Johnson","age": 23,"sex": "M"}]]};
const result = [].concat.apply([], db_parsed.data).filter(obj => obj.age === 22);
console.log(result);

Append Multiple objects into single array

I have an array of objects of the structure coming from server response of iterated array object like as sample
array[1] ={
"ID": "123",
"Name": "John",
"Age": "15"
}
array[2] ={
"ID": "456",
"Name": "Sue",
"Age": "18"
}
array[n] ={
}
But now I want to append the array values if the condition age below 18 in the following structure of as iterated values of above array
Expected Output:
{
"Stud": [{
"ID": "123",
"Name": "John",
"Age": "15"
}, {
"ID": "456",
"Name": "Sue",
"Age": "18"
},{n........
}]
}
var output = { "Stud" : [] };
for (var i = array.length - 1; i >= 0; i--) {
if (array[i].Age < 18) {
output.Stud.push(array[i]);
}
}
console.log(output);
Simply
var output = { "Stud" : array }; //existing 'array'
You can use array#filter to select objects with age less than or equal to 18.
const response = [{
"ID": "123",
"Name": "John",
"Age": "15"
},{
"ID": "456",
"Name": "Sue",
"Age": "18"
},{
"ID": "459",
"Name": "Jaby",
"Age": "20"
}];
const result = response.filter(o => o.Age <= 18);
var output = {'stud' : result};
console.log(output);
Simply iterate and check whether the age is < 18 or not. If so push that to another array.
var array = [];
var array_below_18 = [];
array[0] ={
"ID": "123",
"Name": "John",
"Age": "15"
}
array[1] ={
"ID": "456",
"Name": "Sue",
"Age": "18"
}
array[1] ={
"ID": "456",
"Name": "Sue",
"Age": "14"
}
for(i=0;i<array.length;++i){
if(parseInt(array[i].Age)<18){
array_below_18.push(array[i]);
}
}
var final_object = {
"Stud" : array_below_18
}
console.log(final_object);

How to reduce and filter arrays in javascript?

So I want to filter my array as followed:
Lets say my array1 = ['c', 'd']
My data array =
[{
"userid": "a",
"age": 19,
"name": "john"
}, {
"userid": "c",
"age": 119,
"name": "joy"
}, {
"userid": "d",
"age": 119,
"name": "jesse"
}]
I want to filter out my data array so that only those objects in data array are there whose userid values are present in array1.
Expected result:
new data array = [{
"userid": "c",
"age": 119,
"name": "joy"
}, {
"userid": "d",
"age": 119,
"name": "jesse"
}]
To make you understand better, adding Tushar's solution without lambda expression,
newDataArray = dataArray.filter(function(item) {return array1.includes(item.userid)})
In ES5:
var newDataArray = dataArray.filter(function (item) {
return array1.indexOf(item.userid) !== -1;
});
var a1 = [
{
"userid": "a",
"age": 19,
"name": "john"
},
{
"userid": "c",
"age": 119,
"name": "joy"
},
{
"userid": "d",
"age": 119,
"name": "jesse"
}
];
var a2 = ['c','d'];
var newObj = [];
a1.filter(function(object,index){
var x = object.userid;
a2.filter(function(userId){
if(x==userId){
newObj[index-1] = object;
}
});
});
console.log(JSON.stringify(newObj));

Categories

Resources