Functions indexed and declared in an Array, possibility and alternatives - javascript

I have some issues to organize my code.
Here is an example of what i would like to do:
var Test = {
old: [
get: function(who, when){
returrn({ subject: "Old test 001", text: "The test 001 was perform by "+who });
},
get: function(who, when){
returrn({ subject: "Old test 002", text: "The "+when+" the test 002 was performed"});
}
],
new: [
//Same thing
]
};
The thing is, we apparently can't do that, so i am wondering which is the way to declare functions in an Array ?
I need to do that because each method get() of the array can return a different message and the message can include the variables passed in parameters at different positions in the text, so i have to declare it explicitly.
I don't do like this:
var Test = {
old: [
one: {
get: function(who, when){
returrn({ subject: "Old test 001", text: "The test 001 was perform by "+who });
},
},
two: {
get: function(who, when){
returrn({ subject: "Old test 002", text: "The "+when+" the test 002 was performed"});
}
}
],
new: [
//Same thing
]
};
Because i need to access the content dynamically, like Test.old[test_id].get("toto", "02/04/2013"). and we unfortunatelly can't index things by numerical values in JSON.
However i'll do it like this is there is nothing better.
So what is the best thing to do in this context ?
Thanks !

The question is vague and confusing, but I can see why your code doesn't work. You're conflating arrays and objects. Array literals look like this:
var myArray = [
"first item",
"second item",
{value: "third item"},
["first/only item in fourth item"],
1,
2,
3.14159,
function(a,b) { return a + b; },
"etc."
];
Items in an array are accessed using push, pop, shift, unshift, and numerical indexes.
Object literal look like this:
var myObject = {
one: "some value",
two: {
value: "object values can be anything"
},
123: 456,
"a million": function (a, b) { return a - b; }
};
Items in an object are access using string indexes.
And finally, do you have a returrn() function declared somewhere? In either case, why not just return your return values?

Related

Jquery Object and Array implementation

I have an Object
let data = {
a: 1,
b: 2,
c: {
abc: "ak",
bcd: "gh",
cfv: "ht"
}
}
then I have variables which I need to show with these object value
let abc = "first 1", bcd="sec2", cfv="third3" , def="fourth 4", tdf = "fifth 5";
Now the Object will come in API call it can be any of these variable.
How can I match the variable name with the object data.c.(object key) and concatinate their value.
for example the output should be
As we have (abc, bcd, cfv) as our object key then the output would be
first 1ak ==> that is the value of (abc + data.c["abc"])
sec2gh ==> that is the value of (bcd + data.c["bcd"])
third3ht ==> that is the value of (cfv + data.c["cfv"])
I tried using Object.keys() method so from this method we will get the object keys in array then how can I match with the variable name -
Object.keys(data.c);
==> ["abc", "bcd", "cfv"] (After this how can I proceed to match the variable and show their values?)
Shall I loop throught the object that (data.c)?
Please help me giving some ideas to achieve this implementation.
thank you
If it's possible for you to amend the format of your abc, bcd etc. variables to be the properties in an object, then this problem becomes trivial. You can use flatMap() to create a new array of the output values by linking the properties of the two target objects, like this:
let values = {
abc: "first 1",
bcd: "sec2",
cfv: "third3",
def: "fourth 4",
tdf: "fifth 5"
}
let data = {
a: 1,
b: 2,
c: {
abc: "ak",
bcd: "gh",
cfv: "ht"
}
}
let output = Object.keys(values).flatMap(k => data.c.hasOwnProperty(k) ? values[k] + data.c[k] : []);
console.log(output);

How to ensure a certain key value pair in Typescript Object remains at the last position

I need to create a Typescript Object in which a certain element with the key 'NONE' always remains at last. I need this to ensure that while rendering this object in my HTML page its value appears at bottom.
So basically I need an implementation of myObject.shiftKeyToLastPosition(keyname);
I've tried deleting and re-appending and reduce method. That didn't help.
If all your properties are string, you could try this
const source = {
'Domestic': '1',
'NONE': '0',
'Wild': '2',
};
const { NONE, ...dest } = source;
dest.NONE = source.NONE;
console.log(dest);
Here we are creating a new object without the NONE key and then adding NONE key at the last.
As per ECMAScript 2015 spec, the traversal of an object with string keys would yield keys in order of insertion.
P.S: Assuming that you have only integer and string keys, no Symbol keys.
As pointed out by proxima-b, there's no way to deterministically order an object.
What you can do though, is create an helper function that lets you define the order in which you'd like to display the key/values. The cool thing with Typescript is that you can do that in a type safe way!
const myObject = {
'hello3': 'Value 3',
'hello1': 'Value 1',
'hello2': 'Value 2',
'hello4': 'Value 4',
} as const;
function orderObjectToArrayKeyValue<Obj>(obj: Obj, orderKeys: { [key in keyof Obj]: number }): { key: keyof Obj, value: Obj[keyof Obj] }[] {
return Object
.entries<number>(orderKeys)
.sort(([, order1], [, order2]) => order1 < order2 ? -1 : 1)
.map(([key]) => ({ key, value: obj[key as keyof Obj] }) as { key: keyof Obj, value: Obj[keyof Obj] });
}
With the above example, if you call:
console.log(orderObjectToArrayKeyValue(myObject, {
hello1: 1,
hello2: 2,
hello3: 3,
hello4: 4,
}));
You'll get
[
{
"key": "hello1",
"value": "Value 1"
},
{
"key": "hello2",
"value": "Value 2"
},
{
"key": "hello3",
"value": "Value 3"
},
{
"key": "hello4",
"value": "Value 4"
}
]
Then using the framework of your choice, it'll be really easy to loop over that array and display the values (+ use the key if needed).
Here's a live example (press enter while focusing the left side and it'll run the code, the output will be displayed in your console).

What's the benefit of using an array of key: value pairs over a single object?

In a few different places I've seen the following being used:
const arr = [
{ key: "someKey", value: 1 },
{ key: "anotherKey", value: true },
{ key: "yetAnotherOne", value: "hello world" },
];
To me, it seems more logical to use this structure:
const ob = {
someKey: 1,
anotherKey: true,
yetAnotherOne: "hello world",
};
Is there an advantage when using an array like this?
Arrays are explicitly ordered.
An array is typically used for a list of similar objects. Some advantages would be:
having a selection of array-specific methods to e.g. to filter/sort the objects
In an array of objects it would be possible to use the same key-property multiple times. In an object these would be overwritten.
That's all I could think of. Hope it's helpful ;).
That said I would normally recommend using an object if the above is not relevant.
In your example, it would be better to use the object because it means you can access the value of the property faster and easier using something like ob.anotherKey without having to use a loop or having to know the index in the array.
However, this might not always be the case...
Slightly different from the example above:
const people = [
{ firstName: "someKey", lastName: 1 },
{ firstName: "anotherKey", lastName: true },
{ firstName: "yetAnotherOne", lastName: "hello world" },
];
Is much easier to understand and a better representation of the data and than...
const people = {
someKey: 1,
anotherKey: true,
yetAnotherOne: "hello world",
};
This also requires previous knowledge that each key is the firstName and each value is the lastName.

array difference in javascript

I know this will be so simple but I am trying this for two days so I finally decided to take help from you guys...
I have tried this probably the same question as mine but it is not giving me the answer.
ok so these are the two array
a = [{toNumber: "123", message: "Hi Deep "}, {toNumber: "321", message: "Test1"}]
b = [{toNumber: "321", message: "Test2"}, {toNumber: "123", message: "Hi Deep "}]
What I want is
diff = [{toNumber: "321", message: "Test2"}]
so quick help would be much appriciated.
So with your code you need to look at the other object and see if it has any keys that match. If it matches, you need to see if the message matches. So you can make a look up object that has the list of ids. You can than loop over your second array and see if they march.
var a = [
{toNumber: "123", message: "Hi Deep "},
{toNumber: "321", message: "Test1"}
]
var b = [
{toNumber: "321", message: "Test2"},
{toNumber: "123", message: "Hi Deep "}
]
// create the lookup from the first array
var lookup = a.reduce( function (lookUpObj, entryA) {
// set the object property with the toNumber property
lookUpObj[entryA.toNumber] = entryA.message
return lookUpObj
}, {})
// Now loop over the array and look for the differences
var diff = b.reduce(function (arr, entryB) {
// grab the entry from the lookup object we created
var orginalMessage = lookup[entryB.toNumber]
// if we do not have it listed OR the message is different
// add it to the list as changed.
if (!orginalMessage || orginalMessage !== entryB.message) {
arr.push(entryB)
}
return arr
}, [])
console.log(diff)
Now that will match any differences from a to b. If anything was removed in B that is not in A it will not be caught.
Where is the problem ???
const a =
[ { toNumber: "123", message: "Hi Deep " }
, { toNumber: "321", message: "Test1" }
]
const b =
[ { toNumber: "321", message: "Test2" }
, { toNumber: "123", message: "Hi Deep " }
]
const diff = b.filter(eB=>!a.some(eA=>( eA.toNumber===eB.toNumber
&& eA.message===eB.message )))
document.write( JSON.stringify( diff ) )

Loop through an array of objects and get where object.field equals value

I'm currently working on a small application where I have to loop through an enormous array of objects. What would be the most efficient method to perform this?
var array = [
{
id: "1",
name: "Alpha"
},
{
id: "2",
name: "Beta"
},
...
];
I'd like to get each object where name equals "Alpha". I'm currently using a simple if statement to filter the objects with a different name value out, but I wonder if there's a more efficient way to do this, performance-wise.
It's worth to mention that I'll push the matching results into a new array.
No, there is no more efficient way.
The alternative is to build and maintain some kind of internal data structure which allows you to find the desired elements faster. As usual, the trade off is between the work involved in maintaining such a structure vs the time it saves you.
I don't have any way about which I would know it's more effective.
But if you had your objects ordered by name you could stop your search imideatly upon reaching an object whose name is not equal to "Alpha".
To find the first object you're looking for you can use binary search and from this Object you go up and down until at both ends you reach an object which isn't named "Alpha" or the end of array.
This is only a way of optimizing and will require time to sort the array and also will take more time when adding an element.
There's a JavaScript function exactly for this kind of task. Filter
From the Docs
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Here is a small example by code for getting all element from array which has a certain 'name' field:
const arr = [
{name: 'Abc'},
{name: 'Xyz'},
{name: 'Lmn'},
{name: 'Xyz'},
{name: 'Xyz'}
];
let response = findByName('Xyz');
console.log(response);
function findByName (name) {
return arr.filter((element) => {
return element.name = name;
});
}
If you need more than one time a collection with a given name, you could use an object with the names as hashes and have instantly access to the items.
var array = [{ id: "1", name: "Alpha" }, { id: "2", name: "Beta" }, { id: "3", name: "Beta" }, { id: "4", name: "Gamma" }, { id: "5", name: "Beta" }, { id: "2", name: "Alpha" }],
hash = Object.create(null);
array.forEach(function (a) {
if (!hash[a.name]) {
hash[a.name] = [];
}
hash[a.name].push(a);
});
console.log(hash);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Categories