how to check for properties in an array - javascript

I am making a service call where I get back some data. For example:
var response = [
{id: 1, name: 'text1'},
{id: 2, name: 'text2'}
];
This array represents the most possible data I could get back. In other instances I may get back an empty array, an array with only one of those objects(either or of the objects inside the array).
I'd like to somehow loop through my array and check the id of each on=bject to set a flag for the front end to display other data. How do I properly do checks for the id's in the array for the scenarios I mentioned above?

Use Array.some()
var response = [{ id: 1, name: "text1" }, { id: 2, name: "text2" }];
var exists = (id, arr) => arr.some(e => e.id === id);
var id1Exists = exists(1, response);
var id2Exists = exists(2, response);
var id3Exists = exists(3, response);
console.log({ id1Exists, id2Exists, id3Exists });

var response = [
{id: 1, name: 'text1'},
{id: 2, name: 'text2'}
];
let flag
response.length > 0 && response.forEach(el => {
// JUST CHECKING IF ID IS PRESENT AND EQUAL TO 1
// YOU CAN CHANGE ACCORDINGLY
flag = el.id && el.id === 1 ? true : false
})
console.log(flag)

Here I write a function to find a certain object inside your array, I think this must help you:
public function getMyId($myArray, $id)
{
foreach($myArray as $key => $element){
$arrayFromObject = (Array) $element;
foreach($arrayFromObject as $keyObject => $valueObject){
if($valueObject['id'] == $id)
{
return $myArray[$key]->$keyObject;
}
}
}
return null;
}
For each element inside your array I convert object to array to verify if its id is equal to id u're looking for, than I return the array at certain position and certain value, or if you prefer u could just return the $valueObject it will be an array. I hope help u;

Related

find duplicate values in array of objects in javascript

I have two lists in javascript that are of same structure like below:
var required_documents = [{"id":1,"dt":1},{"id":2,"dt":2},{"id":3,"dt":3}];
var existing_documents = [{"id":1,"dt":1},{"id":2,"dt":2},{"id":3,"dt":4}];
I need to remove all records from database that are in existing documents list (i.e "dt") but NOT in required_documents list.
For the above scenario I should remove only {"id":3,"dt":4} and insert {"id":3,"dt":3}. I am not sure how I can compare on just one property. This is below that I found on SOF sometime ago but can't find it again apologies for not referencing it.
required_documents.forEach((obj) => {
const elementInArr2 = existing_documents.find((o) => o.dt === obj.dt);
console.log('found elementinarr: ' + obj.dt);
});
This returns unique objects like dt:1,dt:2,dt:3 but I need dt:4 from the existing documents list as it is the one that is not in the required documents list and needs to be deleted. How can I get just the one that is not in the required documents list.
Assuming both id and dt properties are significant, I would first create a means of hashing an entry and then build a hashed set of required_documents.
Then you can filter out anything from existing_documents that is in the set, leaving only the results you want.
const required_documents = [{"id":1,"dt":1},{"id":2,"dt":2},{"id":3,"dt":3}];
const existing_documents = [{"id":1,"dt":1},{"id":2,"dt":2},{"id":3,"dt":4}];
// a simple stringify hash
const createHash = ({ id, dt }) => JSON.stringify({ id, dt });
const requiredHashSet = new Set(required_documents.map(createHash));
const result = existing_documents.filter(
(doc) => !requiredHashSet.has(createHash(doc))
);
console.log(result);
The hash creation can be anything that produces a comparable entity that can uniquely identify a record.
You need to run it twice to confirm there is no elements left in existing. So create a function and use it.
var required_documents = [{"id":1,"dt":1},{"id":2,"dt":2},{"id":3,"dt":3}];
var existing_documents = [{"id":1,"dt":1},{"id":2,"dt":2},{"id":3,"dt":4}]
let output = [];
output = output.concat(extractUniqueValues(required_documents, output));
output = output.concat(extractUniqueValues(existing_documents, output));
console.log(output)
function extractUniqueValues(input, output){
return input.filter((item)=>{
return !output.find(v => v.dt == item.dt)
})
}
You can do like below
var required_documents = [
{ id: 1, dt: 1 },
{ id: 2, dt: 2 },
{ id: 3, dt: 3 },
];
var existing_documents = [
{ id: 1, dt: 1 },
{ id: 2, dt: 2 },
{ id: 3, dt: 4 },
];
for (let index = 0; index < required_documents.length; index++) {
const element = required_documents[index];
for (var i = existing_documents.length - 1; i >= 0; i--) {
const child = existing_documents[i];
if (element.id === child.id && element.dt === child.dt) {
existing_documents.splice(i, 1);
} else {
required_documents.push(element);
}
}
}
LOG not exist [{"dt": 4, "id": 3}]
LOG unique items [{"dt": 1, "id": 1}, {"dt": 2, "id": 2}, {"dt": 3, "id": 3}]
If you don't care about time complexity, something this should work:
var new_documents = existing_documents.filter(ed => {
return required_documents.find(rd => rd.dt == ed.dt);
});
Edit Okay, I just reread your question and I'm a bit confused. Do you want the object {id: 3, dt: 3} inside the new array as well?

How to find if an object exist in an array [array is coming from localstorage]

I created an empty array in localStorage
localStorage.setItem('items', JSON.stringify([]))
and then fetching that empty array like this :
let fetchedItems = JSON.parse(localStorage.getItem('items'));
After fetching the Array I want to append some objects in the same.
Array of Objects
let objects = [
{
id: '37f60b13-bb3a-4919-beff-239207745343',
body: '1',
},
{
id: '26c5b0fa-b15f-4a50-9a56-5880727a8020',
body: '2',
},
{
id: '37f60b13-bb3a-4919-beff-239207745343',
body: '1',
},
];
The first and last object have same id
Right now what I am doing is, as I don't want to save or append duplicate objects (by id key) in array/localstorage:
function saveItemsInLocalStorage(item) {
let items;
if (localStorage.getItem('items') === null) {
items = [];
} else {
items = JSON.parse(localStorage.getItem('items'));
}
items.push({
id: item.id,
body: item.body,
});
localStorage.setItem('items', JSON.stringify(items));
}
objects.forEach((object) => {
fetchedItems.forEach((fetchedItem) => {
if (fetchedItem.id !== object.id) {
saveItemsInLocalStorage(object)
}
});
});
The above code is not working. I have also tried reduce method.
Note initially array is empty
Let us take an example and try understanding , how you can do it with your code :
let obj = {name:"user",id:1};
let arr = [{name:"user",id:2},{name:"user",id:3}];
let present = false ;
arr.map(val=>{
if(JSON.stringify( {...val})===JSON.stringify({...obj}) )
present = true ;
})
if(present)console.log("The object is present")
else console.log("The object is not present");

How to use an object to delete it from objects array javascript?

I have an array of objects and I want to check whether a given object is present in the array and if yes,I want to delete that,If not I have to add it to the array.
I am doing this:
var arr=[
{
name: "Jack",
type: "Jill",
},
{
name: "Heer",
type: "Ranjha",
},
{
name: "laila",
type: "Majnu",
};
]
var tosearch = {
name: "Jack",
type: "Jill",
};
if(arr.includes(tosearch))
{
//I want to delete it from the arr.
}
else
arr.push(tosearch)
How can I achieve the above implementation?
Thanks
You can use this code
arr = arr.filter(item => item !== tosearch)
but, there is better way for handle this you can add an id field for each object and wherever you want to check and find specific item you can use that id
arr = arr.filter(item => item.id !== tosearch.id)
Deleting an element from an array using filter. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
const newArray = existingArray.filter(element => element.id != deleteId);
Searching I usually use a simple findIndex. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
const doesElementExist = arr.findIndex(element => element.id === selectedId);
if (doesElementExist > 0) { // Delete element }
This relies on you having a unique identifier in the object potentially the name? I am not sure what your data will be.
Issue
Array.prototype.includes only works for primitives and object via shallow reference equality, i.e. if they are the same object in memory.
Solution
Create a utility to check if the array contains some element where every property of the "search" object is equal.
const arrayContainsObject = (array, object) =>
array.findIndex((el) =>
Object.entries(object).every(([key, value]) => el[key] === value)
);
This example returns the index of the element if found, otherwise it returns -1.
You can use this to either filter the element from the array or append it.
let result;
const index = arrayContainsObject(arr, toSearch);
if (index !== -1) {
result = arr.filter((el, i) => i !== index);
} else {
result = arr.concat(toSearch);
}
const arr = [
{
name: "Jack",
type: "Jill"
},
{
name: "Heer",
type: "Ranjha"
},
{
name: "laila",
type: "Majnu"
}
];
const toSearch = {
name: "Jack",
type: "Jill"
};
const arrayContainsObject = (array, object) =>
array.findIndex((el) =>
Object.entries(object).every(([key, value]) => el[key] === value)
);
let result;
const index = arrayContainsObject(arr, toSearch);
if (index !== -1) {
result = arr.filter((el, i) => i !== index);
} else {
result = arr.concat(toSearch);
}
console.log(result);
You can use Array.prototype.filter to achieve filtering:
/** utils.js */
// default options can be set, here we will create search filter which pick from id
const defaultSearchFilterOptions = { key: 'id', pick: true }
/**
* #description
* factory to create array filter utilities
* #params {object} [options={}] - options used to generate the new filter
* #params {string} [options.key='id'] - key used for comparing
* #params {boolean} [options.pick=true] - inverse the filter (with/without)
* #params {string} options.search - exact match to search (can be improved with a regex or whatever etc..
* #returns {function} filter - function that can be used with `Array.prototype.filter`
*/
function createSearchFilter(options = {}) {
// apply user's options on top of default options, user MUST pass at least "search" options
const { key, search, pick } = { ...defaultSearchFilterOptions, ...options }
// return a filter function, based on computed options
return (item) => pick ? item[key] === search : item[key] !== search
}
/** app.js */
// data
var arr = [
{
name: "Jack",
type: "Jill",
},
{
name: "Heer",
type: "Ranjha",
},
{
name: "laila",
type: "Majnu",
}
];
// using factory, create a filter on name where value is "jack"
const filterInJack = createSearchFilter({
key: 'name',
search: 'Jack',
});
// using factory, create a filter on name where value is not "jack"
const filterOutJack = createSearchFilter({
key: 'name',
search: 'Jack',
pick: false,
});
/** Results */
console.log(arr.filter(filterInJack));
console.log(arr.filter(filterOutJack));
Source: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
If the number of properties are fixed(in your case its 2 name and type) and you know them before running then you can simply use this.
This approach may not be an ideal one but if the data is of this type then i guess this might be might be a good and easy to understand approach
//here i is the index of a object in arr
if(arr[i].name == tosearch.name && arr[i].type == tosearch.type) {
//delete it
} else {
arr.push(tosearch);
}

i wanna return correctly children's object. how can i?

function Ha8(arr, id) {
let result = [];
for(let i = 0; i < arr.length; i++) {
if(Array.isArray(arr[i].children)) {
// if it is a array, it going to be run recursive
result.push(arr[i].children)
const col = Ha8(result[i], id);
if(col === id) {
// find it in array in array
return result
// then return the id object,
} else {
continue; // still can't find.. go ahead!
}
} else if (arr[i]['id']===id) {
return arr[i] // will return valid id object
}
return null // if its none , return null, or parameter id is undefined.
}
}
I m write Intended direction. but its not work..
how can i fix ? give me some tip please.
let input = [
{
id: 1,
name: 'johnny',
},
{
id: 2,
name: 'ingi',
children: [
{
id: 3,
name: 'johnson',
},
{
id: 5,
name: 'steve',
children: [
{
id: 6,
name: 'lisa',
},
],
},
{
id: 11,
},
],
},
{
id: '13',
},
];
output = Ha8(input, 5);
console.log(output); // --> { id: 5, name: 'steve', children: [{ id: 6, name: 'lisa' }] }
output = Ha8(input, 99);
console.log(output); // --> null
I wanna return like that, but only return 'null' ..
need to check children's id and return children's object by using recursive.
so i write like that. but i have no idea..
how to return correctly children id's element?
I will give you an answer using a totally different approach, and using the magic of the JSON.stringify() method, more specifically the replacer optional parameter, which allows the use of a callback function that can be used as a filter.
As you can see, it simplifies a lot the final code. It could also be modified to introduce not only an id, but also any key or value, as I did in my final approach.
EDIT: Following your suggestion, as you prefer your function to be recursive, I recommend you to use the Array.reduce() method. It allows an elegant iteration through all the properties until the needs are met.
Using null as initial value, which is the last argument of the reduce method, it allows to iterate through all fields in the array in the following way:
The first if will always be skipped on the first iteration, as the initial value is null.
The second if will set the currentValue to the accumulator if the property id exists and is equal to the value you are trying to find
The third if, which you could add an Array.isArray() to add a type validation, will check if the property children exists. As it is the last one, it will only work if all the other conditions aren't met. If this property exists, it will call again Ha8Recursive in order to start again the process.
Finally, if neither of this works, it should return null. The absence of this last condition would return undefined if the input id doesn't exist
const Ha8 = (array, inputKey, inputValue) => {
let children = null;
JSON.stringify(array, (key, value) => {
if (value[inputKey] && value[inputKey] === inputValue) {
children = value;
}
return value;
});
return children;
};
const Ha8Recursive = (array, inputKey, inputValue) => {
return array.reduce((accumulator, currentValue) => {
if (accumulator) {
return accumulator;
} else if (currentValue[inputKey] && currentValue[inputKey] === inputValue) {
return currentValue;
} else if (currentValue.children) {
return Ha8Recursive(currentValue.children, inputKey, inputValue);
} else {
return null;
}
}, null)
}
const input = [{"id":1,"name":"johnny"},{"id":2,"name":"ingi","children":[{"id":3,"name":"johnson"},{"id":5,"name":"steve","children":[{"id":6,"name":"lisa"}]},{"id":11}]},{"id":"13"}];
console.log('JSON stringify function');
console.log(Ha8(input, 'id', 5));
console.log('Recursive function')
console.log(Ha8Recursive(input, 'id', 5));

Merged array search functionality is not working

I'm having two data arrays which are coming from API and sample arrays would be like this
Array 1
[
{userId: 1
description: "Student"
imagePath: "test.png"
status: 1
}]
Array 2
[
{id: 85
accountName: "Rahul"
accountNumber: "11145678"
}
]
In my reactnative app view there's search bar and user should be able to search from these two arrays. So I merged these two arrays into one using
this.searchArray =this.filterArray[0].concat(this.filterArray[1])
So, my searchArray is a single array with Array1 and Array2 data. sample below
[
{userId: 1
description: "Student"
imagePath: "test.png"
status: 1
},
{id: 85
accountName: "Rahul"
accountNumber: "11145678"
}]
My search function is below (I need to search from account number or description)
//Search Filter
searchFilter =searchText=>{
const searchTextData = searchText.toUpperCase();
const userSearch = this.searchArray.filter(item => {
const itemData = `${item.description && item.description.toUpperCase()} ${item. accountName && item.accountName.toUpperCase()}`;
return itemData.indexOf(searchTextData) > -1;
});
}
The search functionality is not working with accountName. It's not getting any results. But if I remove ${item. accountName && item.accountName.toUpperCase()} , then it's working showing data with description. But I need to filter from both
In your array one object can have description or accountNumber so do a check if that exists include it in the itemData variable.
Try doing this
searchFilter =searchText=>{
const searchTextData = searchText.toUpperCase();
const userSearch = this.searchArray.filter(item => {
const itemData = `${item.hasOwnProperty('description'))?item.description.toUpperCase():''} ${item.hasOwnProperty('accountNumber')?item.accountNumber:''}`;
return itemData.indexOf(searchTextData) > -1;
});
}
First merge the two objects into one:
Object.keys(arr2[0]).forEach(key => {
arr1[0][key] = arr2[0][key]
})
Then create the search function:
function searchObject(obj, value){
return Object.keys(obj).some(key => {
return obj[key] === value
})
}
let arr1=[{userId:1,description:"Student",imagePath:"test.png",status:1}],arr2=[{id:85,accountName:"Rahul",accountNumber:"11145678"}];
Object.keys(arr2[0]).forEach(key => {
arr1[0][key] = arr2[0][key]
})
function searchObject(obj, prop, value){
return obj[prop] === value
}
console.log(searchObject(arr1[0], "accountName", "asdf"))
console.log(searchObject(arr1[0], "accountName", "Rahul"))

Categories

Resources