Find object in an array - javascript

I want to implement some sort of hasObject function with underscore.js.
Example:
var Collection = {
this.items: [];
this.hasItem: function(item) {
return _.find(this.items, function(existingItem) { //returns undefined
return item % item.name == existingItem.name;
});
}
};
Collection.items.push({ name: "dev.pus", account: "stackoverflow" });
Collection.items.push({ name: "margarett", account: "facebook" });
Collection.items.push({ name: "george", account: "google" });
Collection.hasItem({ name: "dev.pus", account: "stackoverflow" }); // I know that the name would already be enough...
For some reason underscores find returns undefined...
What am I doing wrong?

It looks like you are reading underscore documentation too literally, where
they have:
var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
However, this doesn't make any sense for your case, you just want to see if the .name property is equal to
some other object's .name, like this:
var Collection = {
items: [],
hasItem: function(item) {
return _.find(this.items, function(existingItem) { //returns undefined
return item.name === existingItem.name;
});
}
};

You need to check both values for the name and the account.
var Collection = {
this.items: [];
this.hasItem: function(target) {
return _.find(this.items, function(item) {
return item.name === target.name && item.acount === target.account;
});
}
};
Have you considered using Backbone.js? It fulfills all your collection management needs and uses underscore's methods too.
// create a collection
var accounts = new Backbone.Collection();
// add models
accounts.add({name: 'dev.pus', account: 'stackoverflow'});
accounts.add({name: 'margarett', account: 'facebook'});
accounts.add({name: 'george', account: 'google'});
// getting an array.
var results = accounts.where({ name: 'dev.pus', account: 'stackoverflow' });

Related

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));

how to check for properties in an array

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;

How to use lodash to find and return an object from Array?

My objects:
[
{
description: 'object1', id: 1
},
{
description: 'object2', id: 2
}
{
description: 'object3', id: 3
}
{
description: 'object4', id: 4
}
]
In my function below I'm passing in the description to find the matching ID:
function pluckSavedView(action, view) {
console.log('action: ', action);
console.log('pluckSavedView: ', view); // view = 'object1'
var savedViews = retrieveSavedViews();
console.log('savedViews: ', savedViews);
if (action === 'delete') {
var delete_id = _.result(_.find(savedViews, function(description) {
return description === view;
}), 'id');
console.log('delete_id: ', delete_id); // should be '1', but is undefined
}
}
I'm trying to use lodash's find method: https://lodash.com/docs#find
However my variable delete_id is coming out undefined.
Update for people checking this question out, Ramda is a nice library to do the same thing lodash does, but in a more functional programming way :)
http://ramdajs.com/0.21.0/docs/
lodash and ES5
var song = _.find(songs, {id:id});
lodash and ES6
let song = _.find(songs, {id});
docs at https://lodash.com/docs#find
The argument passed to the callback is one of the elements of the array. The elements of your array are objects of the form {description: ..., id: ...}.
var delete_id = _.result(_.find(savedViews, function(obj) {
return obj.description === view;
}), 'id');
Yet another alternative from the docs you linked to (lodash v3):
_.find(savedViews, 'description', view);
Lodash v4:
_.find(savedViews, ['description', view]);
You can do this easily in vanilla JS:
Using find:
const savedViews = [{"description":"object1","id":1},{"description":"object2","id":2},{"description":"object3","id":3},{"description":"object4","id":4}];
const view = 'object2';
const delete_id = savedViews.find(obj => {
return obj.description === view;
}).id;
console.log(delete_id);
Using filter (original answer):
const savedViews = [{"description":"object1","id":1},{"description":"object2","id":2},{"description":"object3","id":3},{"description":"object4","id":4}];
const view = 'object2';
const delete_id = savedViews.filter(function (el) {
return el.description === view;
})[0].id;
console.log(delete_id);
With the find method, your callback is going to be passed the value of each element, like:
{
description: 'object1', id: 1
}
Thus, you want code like:
_.find(savedViews, function(o) {
return o.description === view;
})
You don't need Lodash or Ramda or any other extra dependency.
Just use the ES6 find() function in a functional way:
savedViews.find(el => el.description === view)
Sometimes you need to use 3rd-party libraries to get all the goodies that come with them. However, generally speaking, try avoiding dependencies when you don't need them. Dependencies can:
bloat your bundled code size,
you will have to keep them up to date,
and they can introduce bugs or security risks
for this find the given Object in an Array, a basic usage example of _.find
const array =
[
{
description: 'object1', id: 1
},
{
description: 'object2', id: 2
},
{
description: 'object3', id: 3
},
{
description: 'object4', id: 4
}
];
this would work well
q = _.find(array, {id:'4'}); // delete id
console.log(q); // {description: 'object4', id: 4}
_.find will help with returning an element in an array, rather than it’s index. So if you have an array of objects and you want to find a single object in the array by a certain key value pare _.find is the right tools for the job.
Import lodash using
$ npm i --save lodash
var _ = require('lodash');
var objArrayList =
[
{ name: "user1"},
{ name: "user2"},
{ name: "user2"}
];
var Obj = _.find(objArrayList, { name: "user2" });
// Obj ==> { name: "user2"}
You can use the following
import { find } from 'lodash'
Then to return the entire object (not only its key or value) from the list with the following:
let match = find(savedViews, { 'ID': 'id to match'});
var delete_id = _(savedViews).where({ description : view }).get('0.id')
Fetch id basing on name
{
"roles": [
{
"id": 1,
"name": "admin",
},
{
"id": 3,
"name": "manager",
}
]
}
fetchIdBasingOnRole() {
const self = this;
if (this.employee.roles) {
var roleid = _.result(
_.find(this.getRoles, function(obj) {
return obj.name === self.employee.roles;
}),
"id"
);
}
return roleid;
},

Select all from array where key: name is equal something

I have got array of var players = [] that holds info like userID, userScore etc.. usually I would select specific player by doing something like players[i] where i is a number position in array. But for one bit of my application I do not know this number, but I do know userID And I'm trying to figure out how to update userScore in players array where userID is equal to something, lets say abc_123
for(var i = 0; i < players.length; i++){
if(players[i].userId === 'someId'){
//doSomething(player[i]);
players[i].userScore = 'abc_123';
}
}
You could use the Array.find method:
var players = [ { userId: 123 } ];
var user = players.find(function(item) {
return item.userId === 123;
});
if (user != null) {
// user is the first element in the players array that
// satisfied the desired condition (a.k.a user.userId === 123)
}
Assuming the array items are objects, you can use the filter function:
var player = players.filter(function(p)
{
return p.userID == "something";
}).forEach(function(p) {
p.userScore = "something";
});
You could use the filter function.
var findId = 'jkl';
var theGoose = players.filter(function(user){ return user.userId === findId; }).pop();
var players = [
{
userId: 'abc',
userInfo: 'duck'
},
{
userId: 'def',
userInfo: 'duck'
},
{
userId: 'ghi',
userInfo: 'duck'
},
{
userId: 'jkl',
userInfo: 'goose!'
},
{
userId: 'mno',
userInfo: 'duck'
}];
var findId = 'jkl';
var theGoose = players.filter(function(user){ return user.userId === findId; }).pop();
$('#debug').text( theGoose.userInfo );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="debug"></div>
You might want to use a Dictionary rather than an array. The key can naturally be the player ID. The rest of the information can be put in some object type. Then you can easily access the Dictionary by key.
Try with grep:
var players = [
{score: 10,userId: 1},
{score: 20,userId: 2},
{score: 30,userId: 3}
];
function findByUsrId(id){
return $.grep(players, function(item){
return item.userId == id;
});
};
console.log(findByUsrId(2));
Jsfiddle here: http://jsfiddle.net/pfbwq98k/

Reproducing MongoDB's map/emit functionality in javascript/node.js (without MongoDB)

I like the functionality that MongoDB provides for doing map/reduce tasks, specifically the emit() in the mapper function. How can I reproduce the map behavior shown below in javascript/node.js without MongoDB?
Example (from MongoDB Map-Reduce Docs):
[{ cust_id: "A123", amount: 500 }, { cust_id: "A123", amount: 250 }, { cust_id: "B212", amount: 200 }]
Mapped to -
[{ "A123": [500, 200] }, { "B212": 200 }]
A library that makes it as simple as Mongo's one line emit() would be nice but native functions would do the job as well.
Array.reduce does what you need.
here is documentation: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
I also suggest you to use undescore.js (as in first comment) which has reduce & reduceRight.
http://underscorejs.org/#reduce
If you just neeed to have the emit syntax, it's possible. Scan out the function body and pass in a new emit function.
function mapReduce(docs, m, r) {
var groups = {}
function emit(key, value) {
if (!groups[key]) { groups[key] = [] }
groups[key].push(value)
}
var fn = m.toString()
var body = fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))
var map = new Function('emit', body)
docs.forEach(function (doc) {
map.call(doc, emit)
})
var outs = []
Object.keys(groups).forEach(function (key) {
outs.push({ _id: key, value: r(key, groups[key]) })
})
return outs
}
Edit, forgot example:
var docs = // from above
Array.sum = function (values) {
return values.reduce(function (a, b) { return a + b })
}
mapReduce(docs,
function () {
emit(this.cust_id, this.amount)
},
function (k, values) {
return Array.sum(values)
}
)
// [ { _id: 'A123', value: 750 }, { _id: 'B212', value: 200 } ]
I agree that there are lots of great lib ways to do this, and it's simple to do with Array methods. Here is a fiddle with my suggestion. It's pretty simple, and just uses the forEach Array method. I've done it in a single loop, but there are many other ways.
I haven't done the reduce at the end, as you didn't ask for that, but I hope this helps.
function emit (key, value, data) {
var res = {}; out = [];
data.forEach(function (item) {
var k = item[key];
var v = item[value];
if (k !== undefined && v !== undefined) {
if (res[k] !== undefined) {
out[res[k]][k].push(v);
} else {
var obj = {};
res[k] = out.length;
obj[k] = [v];
out.push(obj);
}
}
});
return out;
}
var data = [{name: 'Steve', amount: 50},{name: 'Steve', amount: 400}, {name: 'Jim', amount: 400}];
emit('name', 'amount', data)) // returns [{"Steve":[50,400]},{"Jim":[400]}]
emit('amount', 'name', data)) // returns [{"50":["Steve"]},{"400":["Steve","Jim"]}]
I've used an object to store the array index for each unique entry. There are lots of versions of this. Probably many better than mine, but thought I'd give you a vanilla JS version.

Categories

Resources