Searching array with multiple keys - javascript

I can see this works fine for searching a simple array:
var arr1 = ['a','b','c','d','e'];
var index1 = arr1.indexOf('d');
console.log("index1:" + index1); // index1:3
When I try to do the same thing for a different kind of array, it doesn't find the "jane" value:
var arr2 = [{"id":0,"name":"petty"},{"id":1,"name":"jane"},{"id":2,"name":"with"}];
var index2 = arr2.indexOf('jane');
console.log("index2:" + index2); // index2:-1
Sorry - I realise I am probably missing something obvious. I have searched on SO / google for searching multi dimensional arrays, but I don't even know if the array in the 2nd example is a 2d / multi dimensional array, so I am probably not searching for the right thing.

You can use findIndex() method to find index of object with specific value.
var arr = [{"id":0,"name":"petty"},{"id":1,"name":"jane"},{"id":2,"name":"with"}];
var index = arr.findIndex(e => e.name == 'jane')
console.log("index: " + index);

First of all: it's not a multi-dimensional array. It's an array consisting of objects. It's one-dimensional. To find an object you need to iterate through an array and check the needed key, e.g.:
arr.findIndex(function(el) { return el.name === 'jane' })

You could check all values of the objects and use Array#findIndex instead of Array#indexOf.
var arr2 = [{ id: 0, name: "petty" }, { id: 1, name: "jane" }, { id: 2, name: "with" }],
index2 = arr2.findIndex(o => Object.values(o).some(v => v === 'jane'));
console.log(index2);

var arr = [{"id":0,"name":"petty"},{"id":1,"name":"jane"},{"id":2,"name":"with"}];
arr.findIndex((item)=>{return item.name=="petty"})
//output is 0

Related

How to count and record number duplicates in array of objects

I have an array and I need to count and record how many times each item is duplicated. For example the following array:
let arr = [
{item:"pen"},
{item:"book"},
{item:"pen"}
];
This should be returned:
let arr = [
{item:"pen", found: 2},
{item:"book", found: 1},
{item:"pen", found: 2}
]
The attribute "found" should indicate how many times an item appears in the array.
you can use two loop one for iteration one for filter i.e
arr.forEach(item => {
item.found = arr.filter(filterObject => filterObject.item == item.item).length;
})
Try like this.
I have looped the array 2 times and found the duplicate elements, then incremented the new found value.
let arr = [
{item:"pen"},
{item:"book"},
{item:"pen"}
];
var newArr = [];
arr.forEach(function(res){
res.found = 0;
arr.forEach(function(data){
if(res.item === data.item){
res.found++;
}
});
newArr.push(res);
});
console.log(newArr);
There are many ways to skin this cat, some more efficient and some more maintainable. Here's a little bit of both (not the most efficient nor maintainable), which should be easy to follow:
let arr = [
{item:"pen"},
{item:"book"},
{item:"pen"}
];
let found = {};
// Find repeated objects
arr.forEach((obj,i)=>{
found[obj.item]=found[obj.item]||[];
found[obj.item].push(i)
})
// Apply totals to original objects
Object.values(found).forEach(indexes=>
indexes.forEach(index=>arr[index].found = indexes.length)
);
console.log(arr);

Pop the last item off of an array without using built in the array.pop() function

I'm trying to complete a problem that involves removing the last item of an array without using the built-in .pop function. Here is the full problem...
Write a function which accepts an array.
The function should remove the last value in the array and return the value removed or undefined if the array is empty.
Do not use the built in Array.pop() function!
Example:
var arr = [1, 2, 3, 4];
pop(arr); // 4
I figured out how to grab the last number with the following code but this obviously doesn't solve the problem.
function pop (array){
for (i=array.length-1; i>array.length-2; i--){
array = array[i]
} return array
}
pop ([1,2,3,4])
Thanks in advance!
A much simpler solution is to just decrease the length of the array by one. No need to create a second array.
function pop (array){
let last = array[array.length-1]; // Store last item in array
array.length = array.length > 0 ? array.length - 1 : 0; // Decrease length
return last; // Return last item
}
// Test function
function logger(ary){
console.log("Original array: " + ary.join(", "), "\n\tItem popped off: " + pop(ary), "\n\tArray contents now: " + ary.join(", "));
}
// Tests
var ary = [1,2,3,4]; logger(ary);
var ary = ["red", "white", "blue", "green"]; logger(ary);
var ary = ["onlyItem"]; logger(ary);
var ary = []; logger(ary);
var ary = [false]; logger(ary);
It seems like simple is better in this case:
const example = [1,2,3,4];
function pop(arr) {
return arr && arr.splice(-1)[0]
}
console.log(pop(example))
console.log(pop(example))
console.log(pop(example))
console.log(pop(example))
console.log(pop(example))
// edge case: should it return undefined or should it throw?
console.log(pop())
EDIT: This includes a null and empty check.
var array = [1, 2, 3, 4, 5];
function pop(array) {
return array && array.splice(-1)[0]
}
console.log(pop(array));
console.log(pop(array));
console.log(pop(array));
console.log(pop(array));
console.log(pop(array));
console.log(pop(array));
console.log(array);
I think what you are looking for is Array.prototype.slice(). You can use the length property of the array to determine whether it is empty and then return the last entry using slice.
const example = [1,2,3,4];
const emptyExample = [];
const pop = group => group.length > 0
? group.slice(group.length - 1)[0]
: undefined;
const answers = [ pop(example), pop(emptyExample) ];
console.log(answers);
Edit from comment
Example should remove from the array while returning last entry so Array.prototype.splice is probably the better function here.
const example = [1,2,3,4];
const emptyExample = [];
const pop = group => (Array.isArray(group) && group.length > 0)
? group.splice(group.length - 1, 1)[0]
: undefined;
const initialExample = [ ...example ];
const answers = [
pop(example),
pop(emptyExample),
{ initialExample, updatedExample: example, emptyExample }
];
console.log(answers);
Array.prototype.splice(start[, deleteCount[, item1[, item2[, ...]]]])
The splice() method changes the contents of an array by removing existing elements and/or adding new elements.
...
Return value: An array containing the deleted elements. If only one element is removed, an array of one element is returned. If no elements are removed, an empty array is returned.
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
What this means is that so long as the input to the function is an instance of Array, we can call Array#splice(-1) to remove the last element. If there are no elements, this will return an empty array. Because we will always be getting either an array with one element or an empty array, we can access the first element using [0]. If the array is empty, this will be undefined.
So, check that that input is an array, then return Array#splice(-1)[0] if it is or undefined if it is not.
function pop(input) {
let output;
if(input instanceof Array) {
output = input.splice(-1)[0]
}
return output
}
function test(input) {
console.log({
before: input && Array.from(input),
popped: pop(input),
after: input
})
return test
}
test( [ 1, 2, 3, 4 ] )( [ 1 ] )( [ ] )( )( [ , , , ] )
You could use Array.splice()
function pop(arr) {
return arr.splice(-1)[0];
}
This will delete the last item in the array and return it.

How to find the name property from an array of Objects

I am trying to get the value from an array of objects given the id, but I am not able to make it working. The problem is that I have an array of objects, so I don't know how to iterate over them. I know using the .map method could be a possible solution, but I'm new on this.
my method is that given a Id, it has to return me the name from the same object.
How could I iterate over them? I am using this actually:
getName(field_id: any): any {
var aux = 0;
var obj = this.customFields[aux].filter(function (obj) {
return obj.name === field_id;
})[0];
aux ++;
}
where aux is an iterator. Ofc is not working.
considering array containing the objects, you can just use the filter function, no neeed to use the indexer
var arr = [
{id: 1, name: "something"},
{id: 2, name: "something1"},
{id: 3, name: "something2"},
{id: 4, name: "something3"},
{id: 5, name: "something4"}
]
var id=3
var obj = arr.filter(function(obj) {
return obj.id === id;
})
console.log(obj[0].name)
I think your issue is that you compare the name with the id. If you want to avoid loops:
// This find the correct entry corresponding to the id you are looking for
var correctField = this.customFields.find(function(field) {
return field.id === field_id;
});
// Then you get the name from the entry
var nameToFind = correctField && correctField.name;
You might have to replace find depending on your browser support.
A way to replace it:
this.customFields.filter()[0]
You can simply use for loop as below
var arr = [{id:1,name:"abc"},{id:2,name:"pqr"},{id:3,name:"lmn"}]
function getName(id){
for(var i=0;i<arr.length;i++)
if(arr[i].id==id)
return arr[i].name;
return null
}
getName(2);// pqr

How can I push an object into an array?

I know it's simple, but I don't get it.
I have this code:
// My object
const nieto = {
label: "Title",
value: "Ramones"
}
let nietos = [];
nietos.push(nieto.label);
nietos.push(nieto.value);
If I do this I'll get a simple array:
["Title", "Ramones"]
I need to create the following:
[{"01":"Title", "02": "Ramones"}]
How can I use push() to add the object into the nietos array?
You have to create an object. Assign the values to the object. Then push it into the array:
var nietos = [];
var obj = {};
obj["01"] = nieto.label;
obj["02"] = nieto.value;
nietos.push(obj);
Create an array of object like this:
var nietos = [];
nietos.push({"01": nieto.label, "02": nieto.value});
return nietos;
First you create the object inside of the push method and then return the newly created array.
can be done like this too.
// our object array
let data_array = [];
// our object
let my_object = {};
// load data into object
my_object.name = "stack";
my_object.age = 20;
my_object.hair_color = "red";
my_object.eye_color = "green";
// push the object to Array
data_array.push(my_object);
Using destructuring assignment (ES6)
const nieto = {label: 'title', value: 'ramones' }
const modifiedObj = {01: nieto.label, 02: nieto.value}
let array = [
{03: 'asd', 04: 'asd'},
{05: 'asd', 06: 'asd'}
]
// push the modified object to the first index of the array
array = [modifiedObj, ...array]
console.log(array)
If you'd like to push the modified object to the last index of the array just change the destructured array ...array to the front.
array = [...array, modifiedObj]
Well, ["Title", "Ramones"] is an array of strings. But [{"01":"Title", "02", "Ramones"}] is an array of object.
If you are willing to push properties or value into one object, you need to access that object and then push data into that.
Example:
nietos[indexNumber].yourProperty=yourValue; in real application:
nietos[0].02 = "Ramones";
If your array of object is already empty, make sure it has at least one object, or that object in which you are going to push data to.
Let's say, our array is myArray[], so this is now empty array, the JS engine does not know what type of data does it have, not string, not object, not number nothing. So, we are going to push an object (maybe empty object) into that array. myArray.push({}), or myArray.push({""}).
This will push an empty object into myArray which will have an index number 0, so your exact object is now myArray[0]
Then push property and value into that like this:
myArray[0].property = value;
//in your case:
myArray[0]["01"] = "value";
I'm not really sure, but you can try some like this:
var pack = function( arr ) {
var length = arr.length,
result = {},
i;
for ( i = 0; i < length; i++ ) {
result[ ( i < 10 ? '0' : '' ) + ( i + 1 ) ] = arr[ i ];
}
return result;
};
pack( [ 'one', 'two', 'three' ] ); //{01: "one", 02: "two", 03: "three"}
The below solution is more straight-forward. All you have to do is define one simple function that can "CREATE" the object from the two given items. Then simply apply this function to TWO arrays having elements for which you want to create object and save in resultArray.
var arr1 = ['01','02','03'];
var arr2 = ['item-1','item-2','item-3'];
resultArray = [];
for (var j=0; j<arr1.length; j++) {
resultArray[j] = new makeArray(arr1[j], arr2[j]);
}
function makeArray(first,second) {
this.first = first;
this.second = second;
}
This solution can be used when you have more than 2 properties in any object.
const nieto = {
label: "Title",
value: "Ramones"
}
let nietos = [];
let xyz = Object.entries(nieto)
xyz.forEach((i,j)=>{
i[0] = `${(j+1).toLocaleString("en-US", {
minimumIntegerDigits: 2,
useGrouping: false,
})}`
})
nietos.push(Object.fromEntries(xyz))

Get a list of objects that have the same value for a specific property

I have a bunch of objects that have a .type property assigned them.
All the objects are in an array like this:
var arr = [];
arr[0] = {'type':1,'x':56,'y':2};
arr[1] = {'type':2,'x':1, 'y':23};
arr[2] = {'type':1,'x':23,'y':63};
What i would like to do is return a list of all the objects that have for example type == 1.
Is there any built in way to do or will I have to iterate each one individually and push those that match to a new array?
If iterating all the n elements in the array is of concern, then you could construct your data structure as an object and not an array:
var multimap = {};
multimap[1] = [{'type':1,'x':56,'y':2},{'type':1,'x':23,'y':63}];
multimap[2] = [{'type':2,'x':1, 'y':23}];
and you can retrieve the elements of a particular type in order of 1, like:
multimap[1] will give you the elements of type 1.
Inserting a new element of a particular type into the arr structure:
if(!multimap[type]){
multimap[type] = [];
}
multimap[type].push(element);
in js 1.6 you can use the filter function like so:
var result = arr.filter(function(o){return o.type == 1})
...instead of creating and pushing to a new array inside a for loop
technically both of them do the same thing, but filter is elegant as it abstracts the ugliness
Use the .filter function of the array:
var arr = [{
'type': 1,
'x': 56,
'y': 2
}, {
'type': 2,
'x': 1,
'y': 23
}, {
'type': 1,
'x': 23,
'y': 63
}];
var filtered = arr.filter(function(obj) {
return obj.type === 1;
})
for(i=0;i = arr.length;i++){
if (arr[i].hasOwnProperty('type')) {
alert('have key!');
}
}
Using this you can search any property not just type . If you pass property name as parameter
You can achieve this using the .filter() function in Javascript.
Working Code Snippet:
var arr = [];
arr[0] = {'type':1,'x':56,'y':2};
arr[1] = {'type':2,'x':1, 'y':23};
arr[2] = {'type':1,'x':23,'y':63};
var filteredArr = arr.filter(function(obj) {
return obj.type === 1; // filter the objects with type 1
});
console.dir(filteredArr); // check your console
Readup:
.filter() | MDN
EDIT:
As mentioned by #c.P.u1, the filter iterates the array internally. If you think from the algorithmic point of view, you will have to iterate over the data to filter something out.

Categories

Resources