Retrieve a specific value related to a key from a JSON array - javascript

I have a JSON array as follows
[{"Id": 1,"name":"Test1"},
{"Id": 2,"name":"Test2"},
{"Id": 3,"name":"Test2"}]
And I want to get the name of the Id which equals to 2(Id=2) through angularJS. I am a newbie to angularjs.

Array.find might be what you need:
> arr.find(e => e.Id === 2)
{ Id: 2, name: 'Test2' }

Try the below code:
var jsonArray = [{"Id": 1,"name":"Test1"},
{"Id": 2,"name":"Test2"},
{"Id": 3,"name":"Test2"}];
var name = Object.keys(jsonArray).find(e => {
if(jsonArray[e].Id == 2)
{
console.log(jsonArray[e].name);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Not the prettiest but this works
function findObjectByKey(array, key, value) {
console.log(array);
for (let i = 0; i < array.length; i++) {
console.log("looking for:", i);
if (array[i] !== undefined && array[i][key] === value) {
console.log("found at:", i);
return i;
}
}
return null;
}
array is the array you want to search
key would be 'id' in your case and
value woulde be 2 or whatever you are looking for
it returns the index of the object in the array but can easily be modified to return the name like this:
if (array[i] !== undefined && array[i][key] === value) {
console.log("found at:", i);
return array[i]['name'];
}
I know there is a more efficient way probably but this is what i first thought of

Assuming that you have this array:
var arr = [{"Id": 1,"name":"Test1"},
{"Id": 2,"name":"Test2"},
{"Id": 3,"name":"Test2"}];
You can always use a forEach through your array:
arr.forEach((a) => {if(a.Id == 2) console.log(a.name)});

Try below code,
let userArr = [{"Id": 1,"name":"Test1"},
{"Id": 2,"name":"Test2"},
{"Id": 3,"name":"Test2"}];
let userId = 2;
let item = userArr.find(e => {
return e.Id === userId;
});
console.log(item);
You can use also Filter JS Filter.

Related

Prevent element from being added based on boolean

I have an array of ID's ("world") to iterate. If the world element value exists as myArray[n].id then I want to delete the entire element in myArray. If not, then I want to add it to myArray.
world = ["12424126","12461667","12492468","12761163"]
myArray = [
{"id": "12424126"},
{"id": "12761163"},
{"id": "12492468"}
]
Example: if the first element in world[n] ("12424126") exists in myArray as {"id": "12424126"} then delete the element {"id": "12424126"}
if the first element in world[n] ("12424126") does not exists in myArray, then
myArray.push ({"id":world[n]});
}
for (n = 0; n <= world.length; n++) {
ID = world[n];
finished = false;
if (myArray.find(x => x.id === ID)) {
var index = _.findIndex(myArray, { "id": ID });
if (index > -1) { myArray.splice(index, 1);
finished = true;}
}
if (!finished) // PROBLEM: THE RECORD IS ADDED REGARDLESS OF FINISHED T/F
{myArray.push ({id:ID }); // HOW CAN I FIX THIS ?
}
}
The following code works as you want
world = ["12424126", "12461667", "12492468", "12761163"];
myArray = [{ id: "12424126" }, { id: "12761163" }, { id: "12492468" }];
for (n = 0; n < world.length; n++) {
ID = world[n];
var index = myArray.findIndex((item) => item.id == ID);
if (index > -1) {
myArray.splice(index, 1);
} else {
myArray.push({ id: ID });
}
}
The problem is that your loop will make finished turn from true to false again in a next iteration of the loop. You would need to exit the loop immediately when finished is set to true.
However, this can be better solved with a Set:
const world = ["12424126","12461667","12492468","12761163"];
let myArray = [{"id": "12424126"},{"id": "12761163"},{"id": "12492468"}];
const set = new Set(myArray.map(({id}) => id).concat(world));
myArray = Array.from(set, id => ({id}));
console.log(myArray);
If you don't want to assign to myArray a new array, and not create new objects for those that already existed in the array, then:
const world = ["12424126","12461667","12492468","12761163"];
let myArray = [{"id": "12424126"},{"id": "12761163"},{"id": "12492468"}];
const set = new Set(myArray.map(({id}) => id).concat(world));
myArray.push(...Array.from(set).slice(myArray.length).map(id => ({id})));
console.log(myArray);
This second solution assumes however that myArray did not already have duplicate id values.

Jquery or Javascript - Find the number of occurrences in an array; [duplicate]

I am trying to find the indexes of all the instances of an element, say, "Nano", in a JavaScript array.
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
I tried jQuery.inArray, or similarly, .indexOf(), but it only gave the index of the last instance of the element, i.e. 5 in this case.
How do I get it for all instances?
The .indexOf() method has an optional second parameter that specifies the index to start searching from, so you can call it in a loop to find all instances of a particular value:
function getAllIndexes(arr, val) {
var indexes = [], i = -1;
while ((i = arr.indexOf(val, i+1)) != -1){
indexes.push(i);
}
return indexes;
}
var indexes = getAllIndexes(Cars, "Nano");
You don't really make it clear how you want to use the indexes, so my function returns them as an array (or returns an empty array if the value isn't found), but you could do something else with the individual index values inside the loop.
UPDATE: As per VisioN's comment, a simple for loop would get the same job done more efficiently, and it is easier to understand and therefore easier to maintain:
function getAllIndexes(arr, val) {
var indexes = [], i;
for(i = 0; i < arr.length; i++)
if (arr[i] === val)
indexes.push(i);
return indexes;
}
Another alternative solution is to use Array.prototype.reduce():
["Nano","Volvo","BMW","Nano","VW","Nano"].reduce(function(a, e, i) {
if (e === 'Nano')
a.push(i);
return a;
}, []); // [0, 3, 5]
N.B.: Check the browser compatibility for reduce method and use polyfill if required.
Another approach using Array.prototype.map() and Array.prototype.filter():
var indices = array.map((e, i) => e === value ? i : '').filter(String)
More simple way with es6 style.
const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);
//Examples:
var cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
indexOfAll(cars, "Nano"); //[0, 3, 5]
indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
indexOfAll([1, 2, 3], 4); // []
You can write a simple readable solution to this by using both map and filter:
const nanoIndexes = Cars
.map((car, i) => car === 'Nano' ? i : -1)
.filter(index => index !== -1);
EDIT: If you don't need to support IE/Edge (or are transpiling your code), ES2019 gave us flatMap, which lets you do this in a simple one-liner:
const nanoIndexes = Cars.flatMap((car, i) => car === 'Nano' ? i : []);
I just want to update with another easy method.
You can also use forEach method.
var Cars = ["Nano", "Volvo", "BMW", "Nano", "VW", "Nano"];
var result = [];
Cars.forEach((car, index) => car === 'Nano' ? result.push(index) : null)
Note: MDN gives a method using a while loop:
var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.indexOf(element);
while (idx != -1) {
indices.push(idx);
idx = array.indexOf(element, idx + 1);
}
I wouldn't say it's any better than other answers. Just interesting.
const indexes = cars
.map((car, i) => car === "Nano" ? i : null)
.filter(i => i !== null)
This worked for me:
let array1 = [5, 12, 8, 130, 44, 12, 45, 12, 56];
let numToFind = 12
let indexesOf12 = [] // the number whose occurrence in the array we want to find
array1.forEach(function(elem, index, array) {
if (elem === numToFind) {indexesOf12.push(index)}
return indexesOf12
})
console.log(indexesOf12) // outputs [1, 5, 7]
Just to share another method, you can use Function Generators to achieve the result as well:
function findAllIndexOf(target, needle) {
return [].concat(...(function*(){
for (var i = 0; i < target.length; i++) if (target[i] === needle) yield [i];
})());
}
var target = "hellooooo";
var target2 = ['w','o',1,3,'l','o'];
console.log(findAllIndexOf(target, 'o'));
console.log(findAllIndexOf(target2, 'o'));
["a", "b", "a", "b"]
.map((val, index) => ({ val, index }))
.filter(({val, index}) => val === "a")
.map(({val, index}) => index)
=> [0, 2]
You can use Polyfill
if (!Array.prototype.filterIndex)
{
Array.prototype.filterIndex = function (func, thisArg) {
'use strict';
if (!((typeof func === 'Function' || typeof func === 'function') && this))
throw new TypeError();
let len = this.length >>> 0,
res = new Array(len), // preallocate array
t = this, c = 0, i = -1;
let kValue;
if (thisArg === undefined) {
while (++i !== len) {
// checks to see if the key was set
if (i in this) {
kValue = t[i]; // in case t is changed in callback
if (func(t[i], i, t)) {
res[c++] = i;
}
}
}
}
else {
while (++i !== len) {
// checks to see if the key was set
if (i in this) {
kValue = t[i];
if (func.call(thisArg, t[i], i, t)) {
res[c++] = i;
}
}
}
}
res.length = c; // shrink down array to proper size
return res;
};
}
Use it like this:
[2,23,1,2,3,4,52,2].filterIndex(element => element === 2)
result: [0, 3, 7]
findIndex retrieves only the first index which matches callback output. You can implement your own findIndexes by extending Array , then casting your arrays to the new structure .
class EnhancedArray extends Array {
findIndexes(where) {
return this.reduce((a, e, i) => (where(e, i) ? a.concat(i) : a), []);
}
}
/*----Working with simple data structure (array of numbers) ---*/
//existing array
let myArray = [1, 3, 5, 5, 4, 5];
//cast it :
myArray = new EnhancedArray(...myArray);
//run
console.log(
myArray.findIndexes((e) => e===5)
)
/*----Working with Array of complex items structure-*/
let arr = [{name: 'Ahmed'}, {name: 'Rami'}, {name: 'Abdennour'}];
arr= new EnhancedArray(...arr);
console.log(
arr.findIndexes((o) => o.name.startsWith('A'))
)
We can use Stack and push "i" into the stack every time we encounter the condition "arr[i]==value"
Check this:
static void getindex(int arr[], int value)
{
Stack<Integer>st= new Stack<Integer>();
int n= arr.length;
for(int i=n-1; i>=0 ;i--)
{
if(arr[i]==value)
{
st.push(i);
}
}
while(!st.isEmpty())
{
System.out.println(st.peek()+" ");
st.pop();
}
}
When both parameter passed as array
function getIndexes(arr, val) {
var indexes = [], i;
for(i = 0; i < arr.length; i++){
for(j =0; j< val.length; j++) {
if (arr[i] === val[j])
indexes.push(i);
}
}
return indexes;
}
Also, findIndex() will be useful:
var cars = ['Nano', 'Volvo', 'BMW', 'Nano', 'VW', 'Nano'];
const indexes = [];
const searchedItem = 'NaNo';
cars.findIndex((value, index) => {
if (value.toLowerCase() === searchedItem.toLowerCase()) {
indexes.push(index);
}
});
console.log(indexes); //[ 0, 3, 5 ]
Bonus:
This custom solution using Object.entries() and forEach()
var cars = ['Nano', 'Volvo', 'BMW', 'Nano', 'VW', 'Nano'];
const indexes = [];
const searchableItem = 'Nano';
Object.entries(cars).forEach((item, index) => {
if (item[1].toLowerCase() === searchableItem.toLowerCase())
indexes.push(index);
});
console.log(indexes);
Note: I did not run run all tests

Push and replace the value in array

I am creating a project using Angular. During the development, I am facing a problem when pushing values to my array. My requirement is that I want to push the value to the array unless the value already exists in the array. If it already exists, then simply replace that value with newer value.
This is my code, which is currently not working:
var obj = {
question_id: "1",
id: "2",
"question": "This is a test"
};
This is the object that I want to push:
this.selectedOptions = [];
if (!this.selectedOptions.some(function(entry) { return entry.question_id === category.question_id;})) {
this.selectedOptions.push(category);
}
Your code will push the item to the array, but it won't replace an existing item.
I'm assuming that its an array of objects, given the entry.question_id part.
What you need is to check if the object exists in the array, and update or push it accordingly. The findIndex method will return the object index, if it exists in the array, or -1 if not.
const entryIndex = this.selectedOptions.findIndex(entry => entry.question_id === category.question_id);
if (entryIndex > -1) {
this.selectedOptions[entryIndex] = category;
} else {
this.selectedOptions.push(category);
}
You could find the index for update or push something new.
let index = this.selectedOptions.findIndex(function (entry) {
return entry.question_id === category.question_id;
});
if (index === -1) {
this.selectedOptions.push(category);
} else {
this.selectedOptions[index].someKey = 'someValue';
}
Try this:
function customUpsert(arr, data) {
const index = arr.findIndex((e) => e.id === data.id);
if (index === -1) {
arr.push(data);
} else {
arr[index] = data;
}
}
Following funcntion checks if "oldVal" exists and replace it with the "newVal" if it does.
var selectedOptions = [1, 2, 3];
function replaceOrAppend(oldVal, newVal) {
let idx = selectedOptions.indexOf(oldVal);
if (idx < 0)
selectedOptions.push(newVal)
else
selectedOptions[idx] = newVal;
}
replaceOrAppend(1, 100);
replaceOrAppend(10, 200);
console.log(selectedOptions);

Extract strings with unique characters from javascript Array

I want to extract only those strings which have unique characters, I have an array of strings:
var arr = ["abb", "abc", "abcdb", "aea", "bbb", "ego"];
Output: ["abc", "ego"]
I tried to achieve it using Array.forEach() method:
var arr = ["abb", "abc", "abcdb", "aea", "bbb", "ego"];
const filterUnique = (arr) => {
var result = [];
arr.forEach(element => {
for (let i = 0; i <= element.length; i++) {
var a = element[i];
if (element.indexOf(a, i + 1) > -1) {
return false;
}
}
result.push(element);
});
return result;
}
console.log(filterUnique(arr));
Want to know is any other way to achieve this task ?
Any suggestion.
I'd .filter by whether the size of a Set of the string is the same as the length of the string:
const filterUnique = arr => arr
.filter(str => new Set(str).size === str.length);
console.log(filterUnique(["abb", "abc", "abcdb", "aea", "bbb", "ego"]));
(a Set will not hold duplicate elements, so, eg, if 4 elements are put into a set and 2 are duplicates of others, the resulting size of the Set will be 2)
You can check by creating sets from strings also, a Set object will always have unique values.
var a = ["abb", "abc", "abcdb", "aea", "bbb", "ego"];
console.log(a.filter(v => v.length === new Set(v).size))

Select item of array of objects from deep property

Say I have this array:
var myArray = [
{
"name": "item 1",
"id": 123
},{
"name": "item 2",
"id": 456
}
];
What would be the proper way to get an item based on the id property? With this example, say I know I want the item for which item.id == 456.
I don't want jquery answers.
Try this:
var item = myArray.filter(function(item) { return item.id === 456; })[0];
You can implement a search function like below:
function searchArray(id) {
for(var i = 0; i < myArray.length; i++) {
if(myArray[i].id == id) {
return myArray[i];
}
}
console.log(id + ' not found');
}
for ( var index = 0; index < myArray.length; index++ ) {
if ( myArray[index].id == 456 )
//Item found
}
try
for (var i in myArray) {
if(myArray[i].id == 456) {
return myArray[i];
}
}

Categories

Resources