I am building a javascript function where I want to add an object to an array IF it is not already present, if it is I just want to update value.
My objects look like this:
[{31652237148248: 12}, {4365124714824: 4}]
How can I check the Array if there is an object with the ID of 31652237148248?
I tried this but it did not work:
var index = cartItems.findIndex((obj => obj[id] == id));
Use the in operator to check if the id is a property of the object:
const cartItems = [{31652237148248: 12}, {4365124714824: 4}];
const id = '4365124714824';
const index = cartItems.findIndex((obj => id in obj));
console.log(index);
You are looking to see if the value of objects property is equal to the id. 31652237148248 is never going to equal 12
so you can just do a type of
var index = cartItems.findIndex(obj => typeof obj[id] !== undefined);
you can do a truthy check - will fail if it is a falsey value.
var index = cartItems.findIndex(obj => obj[id]);
you can use object keys and includes or if first is equal
var index = cartItems.findIndex(obj => Object.keys(obj).includes(id));
var index = cartItems.findIndex(obj => Object.keys(obj)[0] === id);
A bunch of ways to do it
Personally a better way is just to use an object and not an array for the data.
var items = {31652237148248: 12, 4365124714824: 4}
const addItem = (id, count) => {
cartItems[id] = (cartItems[id] || 0) + count
}
const getArray = () =>
Object.entries(items).map(([key, count]) => ({ [key]: count }))
Try
let add = (obj,arr,k=Object.keys(obj)[0]) =>
arr.some( o=> (k in o)&&(o[k]=obj[k]) ) || arr.push(obj)
let data = [{31652237148248: 12}, {4365124714824: 4}]
let add = (obj,arr,k=Object.keys(obj)[0]) =>
arr.some( o=> (k in o)&&(o[k]=obj[k]) ) || arr.push(obj)
// TEST
add({31652237148248: 15}, data);
console.log('update',data);
add({666: 15}, data);
console.log('add',data);
Related
I have a function with params and I am doing a forEach loop to add all the values from the loop.
const data = (sd) => Object.entries(obj).map(([k, g]) => ({
['name']: k,
['data']: g.map(entry => entry[sd]),
['type']: sd
}));
I also need to add another value but it is conditional.
I am then doing to make one giant set
let arr = ['abc', 'xyz'];
let x = [];
arr.forEach(y => {
x = [...x, ...data(y)];
});
console.log(x);
I also want to add another key-value pair to data then arr element is xyz.
I want to add ['id']: k but only when arr elem is xyz and then push it to x.
This is just an example how you can have a conditional key value in your data.
// Try edit message
const data = [1, 2, 3, 4, 5]
const data2 = data.map(item => {
let predefined = {
value: item,
};
if (item === 2) predefined.id = item;
return predefined;
})
console.log(data2)
How to make work findIndex depending of a snapshotkey ?it's not working with the variable but actually work with a manual string ?!
this.state.data = Object {
"date_add": 1574177488383,
"date_upd": 1574178141010,
"question": "1",
"key": "123455566",
}
ref.on('child_changed', snapshot => {
var key = snapshot.key
console.log('the key', key) // return 123455566
})
actually not working like this :
var foundIndex = this.state.data.findIndex(x => x.key == key);
but work like this
var foundIndex = this.state.data.findIndex(x => x.key == '123455566');
var key = "123456";
var data = [{"key":"123456"},{"key": "123"},{"key": "12"}, {"key":"1"}]
var foundIndex = data.findIndex(x => x.key == key);
console.log(foundIndex); //0
var ind = data.findIndex(x => x.key == '12');
console.log(ind); //2
You should use:
var foundIndex = this.state.data.findIndex(x => x.key == x.key);
Im not sure what you are trying to get but, you usefindindex to get the index of a value.
You can see multiple examples here:
Get the index of the object inside an array, matching a condition
Find index of object in javascript by a value
Also the docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
I want to filter one value from my first array and create a second array with the filtered value.
So far I have that but it does not seem very efficient.
const blacklist = bookingsList.filter(booking => booking.id === id);
const newBookingList = bookingsList.filter(booking => booking.id !== id);
Is there a better way to do this?
I think something like this would be good on a large array or if testing the condition is expensive because you would only loop through the array once
const array1 = [];
const array2 = [];
for (var i = 0; i < input.length; i++) {
const value = input[i];
( testCondition(value) ? array1 : array2 ).push(value);
}
You can do it with a single iteration by using forLoop like
const blacklist = [];
const newBookingList = [];
bookingsList.forEach(booking => {
if(booking.id === id) {
blacklist.push(booking)
}
else {
newBookingList.push(booking)
}
}
You can use forEach() and ternary operator:
const bookingsList = [{id:'black'},{id:'new'}];
const blacklist = [], newBookingList = [], id='black';
bookingsList.forEach(booking => booking.id === id? blacklist.push(booking.id) : newBookingList.push(booking.id));
console.log(blacklist);
console.log(newBookingList);
let blacklist = []
let newBookingList = []
const ID = 10;
let bookingsList=[{id:10}, {id:20}]
bookingsList.forEach(booking => booking.id === ID ? blacklist.push(booking) : newBookingList.push(booking))
console.log(newBookingList)
console.log(blacklist)
I think you can use forEach for that:
const newBookingList = [];
const blacklist = [];
bookingsList.forEach(function(booking) {
if(booking.id === id){
blacklist.push(booking)
}
if(booking.id !== id){
newBookingList.push(booking)
}
})
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
You can use splice method to retrive and remove filtered value.
var bookingList = [{id : 1, name : "A"}, {id: 2, name: "B"}];
var sBookingList = bookingList.splice(bookingList.map(function(b){return b.name}).indexOf("A"), 1);
console.log(sBookingList);
console.log(bookingList);
I am trying to add an object to an array if the array already does not have that object.
So I have an array as follows
[{id:1},{id:2},{id:3}]
I want to check if a id:1 exist or not if not then add if yes then show an error or log a message.
I am able to achieve this using a simple array as follows.
let result =[1,2,2,3,1,4,1,4,2,3].filter((el, i, a) => i === a.indexOf(el));
I cannot figure out how to achive the same with array of objects.
Thanks
You can use some to check for duplicates like:
// array with duplicate objects {id:1}
let arr = [{id:1},{id:1},{id:2}]
function duplicateFound(arr){
const ids = arr.map(x => x.id);
return ids.some((item, idx) => ids.indexOf(item) != idx);
}
console.log(duplicateFound(arr));
// array with not duplicates
arr = [{id:1},{id:2},{id:3}]
console.log(duplicateFound(arr));
You can use Array#filter, and check the length:
const arr = [{id:1},{id:2},{id:3}];
const el = { id: 1 };
const exists = arr.filter(({ id }) => id === el.id).length > 0;
console.log(exists);
Or you can use Array#find, which has a slight advantage over Array#filter, since it will stop as soon as an item was found.
const arr = [{id:1},{id:2},{id:3}];
const el = { id: 1 };
const exists = !!arr.find(({ id }) => id === el.id);
console.log(exists);
You can wrap your array with a proxy that has a set trap, to prevent the insertion of duplicates automatically:
const arr = [{id:1},{id:2},{id:3}];
const arrayChangeHandler = {
set: function(target, property, value, receiver) {
if(property === 'length') {
return true;
}
const exists = !!target.find(({ id }) => id === value.id);
if(exists) {
console.log(`Id: ${value.id} exists!`); // you can return false here, and it will throw an error
} else {
target.push(value);
}
return true;
}
};
const pArr = new Proxy(arr, arrayChangeHandler);
pArr.push({ id: 1 });
pArr.push({ id: 10 });
console.log(JSON.stringify(arr));
You could try inserting all values as keys to a new array then flip keys & vals
let arr = "abccba".split('');
let res = [];
arr.forEach((n) => {
res[n] = n;
});
console.log(Object.keys(res));
A concern might be that if your values are numbers then you might need to recast them eg.
res = res.map(n) => +n
I have a list in variable like:
var name_list = some_list
console.log(name_list)
Array[3]
0: Object
name: "Johny"
1: Object
name: "Monty"
2: Object3:
name: "Johny"
I want to get the list with non repetitive list.
How can I do this ?
Update
I tried with this..
var unique_name = [ ...new Set(name_list.map(name => {
return name.name
}))]
It works fine but I want the object that are filtered unique according to name.
Any idea ??
Another approach I don't see in here would be to use a Map
var name_list = [{name: "Johny"}, {name: "Monty"}, {name: "Johny"}];
// Make a mapping of name to object, then pullout objects.
var name_map = new Map(name_list.map(o => [o.name, o]));
var unique_names = [...name_map.values()];
Note, this will take the last object for each name instead of the first, but you could always do name_list.slice().reverse().map( instead of you need specifically the first object found.
reduce over the array keeping a lookup of previous entries to check against.
const arr=[{name:"Johny"},{name:"Monty"},{name:"Johny"}];
function dedupeByKey(arr, key) {
const tmp = {};
return arr.reduce((p, c) => {
const k = c[key];
if (tmp[k]) return p;
tmp[k] = true;
return p.concat(c);
}, []);
}
console.log(dedupeByKey(arr, 'name'));
Or you can filter using a similar approach:
const arr=[{name:"Johny"},{name:"Monty"},{name:"Johny"}];
function dedupeByKey(arr, key) {
const temp = arr.map(el => el[key]);
return arr.filter((el, i) =>
temp.indexOf(el[key]) === i
);
}
console.log(dedupeByKey(arr, 'name'));
Filter to keep only those elements which are the first occurrence of the name (in other words, whose index is the same as the index of the first occurrence):
var name_list = [{name: "Johny"}, {name: "Monty"}, {name: "Johny"}];
var filtered = name_list . filter(
(elt, i, a) => i === a.findIndex(
elt2 => elt.name === elt2.name
)
);
document.getElementById('result').textContent = JSON.stringify(filtered);
<pre id='result'></pre>
This might not be the fastest approach, but it could be the simplest.
You can use this little distinctByProp( theArray, propertyName) function.
I hope it helps
distinctByProp = (theArray, prop) => {
let tempArray = [];
let isFound = obj => tempArray.find( n => n[prop] === obj[prop]);
theArray.forEach( current => !isFound(current) && tempArray.push(current));
return tempArray;
}
Usage is like:
let names_list = [{name: "Johny"}, {name: "Johnyh"}, {name: "Max"}, {name: "Monty"}, {name: "Johnyh"}, {name: "Max"}];
let distinct = distinctByProp(names_list, "name");
console.log(distinct);
I hope it helps
You could use Array#filter().
var name_list = [{ name: "Johny" }, { name: "Monty" }, { name: "Johny" }],
filtered = name_list.filter(a => {
this.my = this.my || Object.create(null);
if (!this.my[a.name]) {
this.my[a.name] = true;
return true;
}
});
document.write('<pre>' + JSON.stringify(filtered, 0, 4) + '</pre>');
This is my resumed form of this type of unique. Not only for one field but for all the root fields of the object.
const unique = l => l.filter(
(e1, i, a) => i === a.findIndex(
e2 => Object.keys(e1)
.map(x => e1[x] === e2[x])
.reduce((x,y) => x && y)
)
)