Cannot get first item of array - arrays

Here's an array printed by a function getTargets();:
{
name = {
isPlayer = true,
isBlocking = false,
username = "yes"
}
}
When I do players = getTargets(); to put this in variable and want to access first variable no matter its name, I have some trouble. I tried those:
players.name.username --displays "yes"
players[0].username --displays nil
players[1].username --displays nil
I want to access first variable of this array no matter what is its value.
How can I do this?

Your code
local players = {
name = {
isPlayer = true,
isBlocking = false,
username = "yes"
}
}
is equivalent to
local players = {}
players.name = {
isPlayer = true,
isBlocking = false,
username = "yes"
}
So there is no index 0 or 1, hence players[0] and players[1] are nil.
players[0].username and players[1].username will cause an error for indexing nil values.
To get the first element of a table of unknown keys simply do this:
local key, value = next(someTable)
https://www.lua.org/manual/5.3/manual.html#pdf-next
When called with nil as its second argument, next returns an initial
index and its associated value.
Keep in mind that:
The order in which the indices are enumerated is not specified, even
for numeric indices.
If you want to make sure you should change your data structures accordingly.
But I cannot give you much advice here as I don't know the purpose of this.
You could have a little function like (simplyfied):
local function addPlayerToList(playerList, playerLookUpTable, player)
table.insert(playerList, player)
playerLookUpTable[player.name] = #playerList
end
Read something about OOP in Lua for nicer and more advanced ideas.

You can try to get the key/name in this way:
local players = {
name = {
isPlayer = true,
isBlocking = false,
username = "yes"
}
}
local FirstPlayer
for k,v in pairs(players) do FirstPlayer=k break end
print(players[FirstPlayer].username)
however there is no guarantee that this will always be the first. But maybe this is your case.

You don't even need a for loop:
n,t = pairs(players)
firstKey, firstValue = n(t)
https://repl.it/JBw1/1
As lhf pointed out, you don't even need pairs, you can simply do
firstKey, firstValue = next(players)

Related

How prevent Object.keys() sort?

The problem with the ECMA standard for sort of Object.keys() is known:
Object.keys() handle all keys with integer (example: 168), including integer as strings (example: "168"), as a integer. The result is, both are the same (168 === "168"), and overwrite itself.
var object = {};
object["168"] = 'x';
object[168] = 'y';
Object.keys(object); // Array [ "168" ]
object[Object.keys(object)]; // "y"
Interestingly, all keys (including pure integer keys) are returned as a string.
The ecma262 wrote about this: All keys will be handle as a integer, expect the key is a String but is not an array index.
https://tc39.es/ecma262/#sec-ordinaryownpropertykeys
That should tell us: 168 === "168". A toString() do not solve the problem.
var object = {};
object[[3].toString()] = 'z';
object[[1].toString()] = 'x';
object[[2].toString()] = 'y';
Object.keys(object);
// Array(3) [ "1", "2", "3" ]
Paradoxically, in this case, only integer apply as "enumerable" (it's ignoring array.sort(), that sort also strings with letters.).
My question about this is simple: How can i prevent the sort function in Object.keys()? I have testet the Object.defineProperties(object, 1, {value: "a", enumerable: true/false}), but that mean not realy enumerable in the case of integer or string or integer-like string. It means only should it be counted with or not. It means "counted" like omit (if it false), not "enumerabled" like ascending or descending.
A answere like that is not a good answer: Please use only letters [a-zA-Z] or leastwise a letter at the first position of keyword.
What I want: That the keys are not sorted, but output in the order in which they were entered, whether integer, string or symbol.
Disclaimer: Please solutions only in JavaScript.
Javascript Objects are unordered by their nature. If you need an ordered object-like variable I would suggest using a map.
To achieve what you're looking for with a map instead of object you'd do something like the below:
var map1 = new Map();
map1.set("123", "c");
map1.set(123, "b");
var iterator1 = map1.keys();
var myarray = [];
for (var i = 0; i < map1.size; i++) {
myarray.push(iterator1.next().value);
}
console.log(myarray);
// Array ["123", 123]
Unfortunately it's not compatible with IE and I'm not sure how else you could achieve what you need without it. A quick Google did return something about jQuery maps, though.
If you don't want to use jQuery and still need to support IE some points are below:
Is there anything stopping you using an array rather than JS object to store the data you need? This will retain the order per your requirements unlike objects. You could have an object entry in each iteration which represents the key then use a traditional foreach to obtain them as an array. I.e.
The array:
var test_array = [
{key: 123, value: 'a value here'},
{key: "123", value: 'another value here'}
];
// console.log(test_array);
Getting the keys:
var test_array_keys = [];
test_array.forEach(function(obj) { test_array_keys.push(obj['key']); } );
// console.log(test_array_keys);
Then if you needed to check whether the key exists before adding a new entry (to prevent duplicates) you could do:
function key_exists(key, array)
{
return array.indexOf(key) !== -1;
}
if(key_exists('12345', test_array_keys))
{
// won't get here, this is just for example
console.log('Key 12345 exists in array');
}
else if(key_exists('123', test_array_keys))
{
console.log('Key 123 exists in array');
}
Would that work? If not then the only other suggestion would be keeping a separate array alongside the object which tracks the keys and is updated when an entry is added or removed to/from the object.
Object Keys sorted and store in array
First Creating student Object. then sort by key in object,last keys to store in array
const student={tamil:100, english:55, sci:85,soc:57}
const sortobj =Object.fromEntries(Object.entries(student).sort())
console.log(Object.keys(sortobj))
use map instead of an object.
let map = new Map()
map.set("a", 5)
map.set("d", 6)
map.set("b", 12)
to sort the keys (for example, to update a chart data)
let newMap = new Map([...map.entries()].sort())
let keys = Array.from(newMap.keys()) // ['a','b','d']
let values = Array.from(newMap.values()) // [5,12,6]

Kotlin - Find matching objects in array

Let's say I have an array of strings and I want to get a list with objects that match, such as:
var locales=Locale.getAvailableLocales()
val filtered = locales.filter { l-> l.language=="en" }
except, instead of a single value I want to compare it with another list, like:
val lang = listOf("en", "fr", "es")
How do I do that? I'm looking for a one-liner solution without any loops. Thanks!
Like this
var locales = Locale.getAvailableLocales()
val filtered = locales.filter { l -> lang.contains(l.language)}
As pointed out in comments, you can skip naming the parameter to the lambda, and use it keyword to have either of the following:
val filtered1 = locales.filter{ lang.contains(it.language) }
val filtered2 = locales.filter{ it.language in lang }
Just remember to have a suitable data structure for the languages, so that the contains() method has low time complexity like a Set.

Laravel 5.4 - Array returning NULL instead of a numeric value

Here's a problem that is bothering me for a while.
I have a service provider to pass data to all views, everytime the sidebar is rendered. like this:
`
public function boot()
{
$userrole = array (DB::table('users')->where('id','=', Auth::id())->value('role'));
$menucase1 = [3,4,9,10];
$menucase2 = [1,2,3,10];
$menucase3 = [1,3,4,9,10];
$menucase4 = [4,9];
$commondata = compact('userrole','menucase1','menucase2','menucase3','menucase4');
view()->share('commondata', $commondata);
View::composer('sidebar', function ($view) {
$userrole = array (DB::table('users')->where('id','=', Auth::id())->value('role'));
$menucase1 = [3,4,9,10];
$menucase2 = [1,2,3,10];
$menucase3 = [1,3,4,9,10];
$menucase4 = [4,9];
$commondata = compact('userrole','menucase1','menucase2','menucase3','menucase4');
$view->with('commondata', $commondata);
});
}`
Doing a {{ dd($commondata) }} returns the correct values for the menucase arrays, but NULL for the $userrole
If i declare the same $userrole variable in a controller and call the variable in the view, the received data is correct.
Why is this happening?
Thanks in advance
Can't understand what are you actually trying to do.
If you want get user role as array, you can using pluck method:
$userRole = User::where('id', Auth::id())->pluck('role')->toArray();
But for current user you can just get the role
$userRole = [Auth::user()->role];
UPD: you also can do it in view without any sharing
{{ Auth::user()->role }}
If your user has many roles from a different table, and you have the relationship defined, you could do
$userrole = Auth::user()->roles->pluck('name');
//will return all the roles names in an array
//Replace name by the actual column you want from 'roles' table.

How to check for Hash value in an array?

Heres my set up
project_JSON = JSON.parse
teamList = Array.new
project = Hash.new()
project["Assignee Name"] = issue["fields"]["assignee"]["displayName"]
project["Amount of Issues"] = 0
if !teamList.include?(issue["fields"]["assignee"]["displayName"])
project_JSON.each do |x|
project["Amount of Issues"] += 1
teamList.push(project)
end
Im having trouble with this line.
if !teamList.include?(issue["fields"]["assignee"]["displayName"])
It always returns true even after the .push. I want to make an array of my team members and list how many times their name appears in my JSON. What am I doing wrong and how do I dynamically refer to a hash value in an if statement(thats where I think its wrong because if I am saying .include?(issue["fields"]["assignee"]["displayName"]) wrong then its nil and the if statement will always be true)?
In your code teamList is an empty array, so it does not include? anything, it will always return false. Now because you are using ! operator it always returns true.
EDIT
If understood it right, you have to loop through the array checking each element for the value specified.
Below is a way to do it, mind you I replaced keys for symbols as it's a good practice in Ruby:
issue = {
:fields => {
:assignee => {
:displayName => 'tiago'
}
}
}
teamList = Array.new
def teamList.has_assignee?(assignee)
self.each do |e|
return e[:assignee] == assignee
end
false
end
project = Hash.new
project[:assigneeName] = issue[:fields][:assignee][:displayName]
project[:amountOfIssues] = 0
teamList.push(project) unless teamList.has_assignee? issue[:fields][:assignee][:dsiplayName]
teamList.push(project) unless teamList.has_assignee? issue[:fields][:assignee][:dsiplayName]
puts teamList.inspect # only one object here
As Sergio pointed out you could use .detect
def teamList.has_assignee?(assignee)
self.detect { |e| e[:assigneeName] == assignee }
end

Lua - How to check if list contains element

I need some help with my lua script for a game. I need to check if my inventory in the game contains any id from a list.
Here's a piece of my list:
local Game_Items = {
{id = 7436, name = "angelic axe", value = 5000},
{id = 3567, name = "blue robe", value = 10000},
{id = 3418, name = "bonelord shield", value = 1200},
{id = 3079, name = "boots of haste", value = 30000},
{id = 7412, name = "butcher's axe", value = 18000},
{id = 3381, name = "crown armor", value = 12000}
}
The following code might look a bit weird since you don't know what it's for, but it's basically this: the list above is a list of items in my game, and inside the game theres an inventory where you can keep items and stuff. Now I want to check if my inventory contains any of those IDs.
I tried adding 2 of the id's manually and it worked, but my list of items contains over 500 items in total and I don't want to write them all out. Is there a way to put the whole list and check if it's in there somehow?
if not table.contains({ 3035, 3043, Game_Items[id] }, tempItemCounter.id) then
This is what I tried so far. Those two first id's work 3035 and 3043, then I tried all my whole list and only check the Ids. but I dont know how to do that. That code does not work. Could anyone just help me include the whole list of id's in the table.contains ?
Basically wanna include my whole list in that line, without typing out all IDs manually.
Shouldn't Game_Items[id] work? Doesn't that mean all the "id" inside "Game_Items"?
Thanks!
No it doesn't mean that. If foo is a table, then foo[id] looks for a field in foo that is called whatever id refers to, such as a string (so if id is 1 you will get foo[1], if id is "bar" you will get foo.bar, etc).
You can't do it in one line, but you can create a function that will allow you to write your if condition. I'm not sure what tempItemCounter is but assuming that your inventory is a map of keys to entries of the form
inventory = {
[1234] = {....},
[1235] = {....},
...
}
where each integer key is unique, and assuming you want true only if all items are in inventory, then you could do this:
function isAllInInventory(items, inventory)
for i,item in ipairs(items) do
if inventory[item.id] == nil
return false
end
end
return true
end
if isAllInInventory(Game_Items, inventory) then
...
end

Resources