Add Dynamic Property To End of Object - javascript

I am creating an object and set its properties dynamically and push it to an array, as below:
var modelData = [];
var data = {}
data['rain'] = '123';
var items = [{name: 'prod', default_id: 1}, {name: 'dev', default_id: 2}]
for (var i = 0; i < items.length; i++) {
var id = items[i].name;
data[id] = items[i].default_id;
}
modelData.push(data)
This works fine but by default it adds the properties in ascending order. I want it to be added to the end of the object, so my properties would be rain, prod, dev instead of dev, prod, rain
Is that possible?
see this jsfiddle console for an example.

Objects don't have a guaranteed order in JS. The closest thing you can get is an array of arrays:
var ordered_object = [];
ordered_object.push(['rain', 'First element']);
ordered_object.push(['prod', 'Second element']);
ordered_object.push(['dev', 'Third element']);
ordered_object.forEach(function(pair) {
var key = pair[0],
value = pair[1];
console.log(key + ': ' + value);
});
It will be ordered, but getting the value of a "property" (they're not really properties any more) is a little more difficult:
function get_value(ordered_object, key) {
for (var i = 0; i < ordered_object.length; i++) {
if (ordered_object[i][0] === key) {
return ordered_object[i][1];
}
}
}

Related

Remove items from array using id with Javascript

I have a function like this: pickListSelect array is has all id (numbers) to delete objects in source array, and target array it is to push elements deleted from source array.
function copy(pickListSelect, source, target) {
var i, id;
for (i = 0; i < pickListSelect.length; i++) {
id = pickListSelect[i];
source.splice(id,1);
}
pickListSelect = [];
}
So what I need is delete specific object from source array. I tried with that code but for example if I need to delete object with id=5, it only deleted item 5 from the list.
The structure of source array is this:
[Object, Object, Object, Object, Object, Object, Object, Object, Object]
0:Object
plantId:1
plantName:"Plant 1"
...the rest of others are similar object
You need to find plant in your source by plantId first, and then delete it from original array and push to target. Open console and it should log deleted plants:
var plants = [
{
plantId: 1,
plantName: 'plant 1'
},
{
plantId: 2,
plantName: 'plant 2'
},
{
plantId: 3,
plantName: 'plant 3'
},
{
plantId: 4,
plantName: 'plant 4'
}
];
function copy(pickListSelect, source, target) {
var i, id, el;
for (i = 0; i < pickListSelect.length; i++) {
id = pickListSelect[i];
el = findPlant(source, id);
source.splice(source.indexOf(el), 1);
target.push(el);
}
}
function findPlant (arr, id) {
return arr.filter(function (plant) {
return plant.plantId == id
})[0]
}
var test = [];
copy([2,3], plants, test);
console.log(test);
When you use .splice you need to pass in the start index at which to splice and the amount of items to splice, try this:
source.splice(i,1); // i is your starting index here
array.splice(start, deleteCount[, item1[, item2[, ...]]])
MDN on .splice
Now in your actual code you need to check to see if the id matches and then splice using the above code:
function copy(pickListSelect, source, target) {
var i, id;
for (i = 0; i < pickListSelect.length; i++) {
if (pickListSelect[i].id === someId) {
source.splice(i,1);
}
}
pickListSelect = [];
}
You can take a look at this fiddler here.
I have used underscore.js to find the correct element from source and move it to the target array.
var copy = function(pickListSelect, source, target) {
for (i = 0; i < pickListSelect.length; i++) {
id = pickListSelect[i];
var deleteIndex = _.findIndex(source, {Id: id});
var deletedItem = source.splice(deleteIndex, 1);
target.push(deletedItem[0])
}
pickListSelect = [];
return target;
}
You're not looking up the index of the source array with a matching id. It might be better to do something like this.
var idsToRemove = {};
// build an object of ids to remove (effectively a hashset)
for (var i = 0; i < pickSelectList.length; i++) {
idsToRemove[pickSelectList[i]] = true;
}
// loop through the source array to find any objects with ids to remove
for (var j = 0; j < source.length; j++) {
if (source[j].plantId in idsToRemove) {
target.push(source.splice(j, 1));
}
}

Convert an array of object to array of string?

I'm having an array of object like this-
var person = [
{name: 'saprsh', age: 22, address:'XYZ'},
{name: 'Ankur', age: 23},
{name: 'Richa', age:25, adddress:'ABX', email:'abc#xyz.co'}
];
now i want output like this
var string_person = [{sparsh22XYZ},{ankur23},{Richa25ABXabc#xyz.co}];
is their any way to get output like this in javascript, jquery, Angular.js.
Any other web used language is approved.
Check out this jsfiddle. You'll see both Array.prototype.reduce and Array.prototype.map used, both with the same results.
This is classic reduce:
var people = person.reduce(function(agg, p) {
return agg.concat([p.name + p.age + p.address]);
}, []);
The above uses Array.prototype.reduce.
In other words, when you want all the properties of an object or array "reduced" into something, then the most semantic go-to option is probably Array.prototype.reduce in this case.
However, Array.prototype.map can also do the job quite cleanly:
var people = person.map(function(p) {
return p.name + p.age + p.address;
});
This is an argument, now, between readability/complexity vs. semantics.
To limit incidental complexity (in the form of readability), I might go for the map function, even though you could argue this is technically a paradigmatic reduction.
Try this, this method suitable for different object names, it will work good.
var person = [
{name: 'saprsh', age: 22, address:'XYZ'},
{name: 'Ankur', age: 23},
{name: 'Richa', age:25, adddress:'ABX', email:'abc#xyz.co'}
];
var result = person.map(function(p){ return Object.keys(p).map(function(k){return p[k]}).join("");})
You can do it like this.
var person = [
{name: 'saprsh', age: 22, address:'XYZ'},
{name: 'Ankur', age: 23, address:'ABC'}
];
var test = person.map(function(one){
var properties = Object.getOwnPropertyNames(one);
return properties.map(function(prop){
return one[prop];
}).join('');
});
console.log(test);
I think it will help you.
var person = [
{name: 'saprsh', age: 22, address:'XYZ'},
{name: 'Ankur', age: 23, address:'ABC'}
];
var stringarray=[];
// $.each(person, function (i, d) {
// stringarray.push(d.name + d.age + d.address);
// });
//for(var i = 0; i < person.length; i++){
// stringarray.push(person[i].name + person[i].age + person[i].address);
//}
var stringarray = person.map(function(p) {
return p.name + p.age + p.address;
});
console.log(stringarray);
Result: ["saprsh22XYZ", "Ankur23ABC"]
Plz Try this one.
I assume you want a array of strings.
[{sparsh22XYZ},{ankur23ABC}]
is not such an array.
If you want
[ "sparsh22XYZ", "ankur23ABC" ]
you can simply go with
Plain old Javascript:
var string_person = [];
for (var i = 0; i < person.length; i++) {
string_person.push(person[i].name+person[i].age+person[i].address);
}
Underscore.js library
If all you need is a list of values of one of the object properties, it's easiest to go with underscore.js library.
var string_person = _.pluck(person, 'name');
http://underscorejs.org/#pluck
Call the below function on any array of Objects with any number of parameters, it will return you what you want.
function getStringArray(array){
var resultArray = [];
for (i = 0; i < array.length; i++) {
var result = "";
var keysArray = Object.keys(array[i]).sort()
for(j = 0; j < keysArray.length; j++){
result = result+array[i][keysArray[j]];
}
resultArray.push(result);
}
return resultArray;
}
var string_person = [];
for(var i = 0; i < person.length; i++){
string_person.push(person[i].name + person[i].age + person[i].address);
}
Updated:
Also You can use Underscore:
var string_person = _.map(person, function(p){return p.name + p.age + p.address;});
I guess you want to join all members of the object to a string. There are two ways to do this:
// iterate through the array of persons
for (var index = 0; index < person.length; index++) {
var obj = person[index]; // save the object temporally
person[index] = ''; // place an empty string at the index of the object
// iterate through all members of the object using the "in"-operator
for (var member in obj) {
person[index] += obj[member]; // add the value of the member to the string
}
}
The problem with this technique is, I cannot guarantee that it will join the values of the members in the order you want. It should join them in the order in which the members were defined.
Anyway this solution works fine but only in your case:
// iterate through the array of persons
for (var index = 0; index < person.length; index++) {
// place a string which contains the joined values of the members in the right order at the index of the object
person[index] = [
person[index].name,
person[index].age,
person[index].address
].join('');
}

push only unique elements in an array

I have array object(x) that stores json (key,value) objects. I need to make sure that x only takes json object with unique key. Below, example 'id' is the key, so i don't want to store other json objects with 'item1' key.
x = [{"id":"item1","val":"Items"},{"id":"item1","val":"Items"},{"id":"item1","val":"Items"}]
var clickId = // could be "item1", "item2"....
var found = $.inArray(clickId, x); //
if(found >=0)
{
x.splice(found,1);
}
else{
x.push(new Item(clickId, obj)); //push json object
}
would this accomplish what you're looking for? https://jsfiddle.net/gukv9arj/3/
x = [
{"id":"item1","val":"Items"},
{"id":"item1","val":"Items"},
{"id":"item2","val":"Items"}
];
var clickId = [];
var list = JSON.parse(x);
$.each(list, function(index, value){
if(clickId.indexOf(value.id) === -1){
clickId.push(value.id);
}
});
You can't use inArray() because you are searching for an object.
I'd recommend rewriting a custom find using Array.some() as follows.
var x = [{"id":"item1","val":"Items"},{"id":"item1","val":"Items"},{"id":"item1","val":"Items"}]
var clickId = "item1";
var found = x.some(function(value) {
return value.id === clickId;
});
alert(found);
Almost 6 years later i ended up in this question, but i needed to fill a bit more complex array, with objects. So i needed to add something like this.
var values = [
{value: "value1", selected: false},
{value: "value2", selected: false}
//there cannot be another object with value = "value1" within the collection.
]
So I was looking for the value data not to be repeated (in an object's array), rather than just the value in a string's array, as required in this question. This is not the first time i think in doing something like this in some JS code.
So i did the following:
let valueIndex = {};
let values = []
//I had the source data in some other and more complex array.
for (const index in assetsArray)
{
const element = assetsArray[index];
if (!valueIndex[element.value])
{
valueIndex[element.value] = true;
values.push({
value: element.value,
selected: false
});
}
}
I just use another object as an index, so the properties in an object will never be repated. This code is quite easy to read and surely is compatible with any browser. Maybe someone comes with something better. You are welcome to share!
Hopes this helps someone else.
JS objects are great tools to use for tracking unique items. If you start with an empty object, you can incrementally add keys/values. If the object already has a key for a given item, you can set it to some known value that is use used to indicate a non-unique item.
You could then loop over the object and push the unique items to an array.
var itemsObj = {};
var itemsList = [];
x = [{"id":"item1","val":"foo"},
{"id":"item2","val":"bar"},
{"id":"item1","val":"baz"},
{"id":"item1","val":"bez"}];
for (var i = 0; i < x.length; i++) {
var item = x[i];
if (itemsObj[item.id]) {
itemsObj[item.id] = "dupe";
}
else {
itemsObj[item.id] = item;
}
}
for (var myKey in itemsObj) {
if (itemsObj[myKey] !== "dupe") {
itemsList.push(itemsObj[myKey]);
}
}
console.log(itemsList);
See a working example here: https://jsbin.com/qucuso
If you want a list of items that contain only the first instance of an id, you can do this:
var itemsObj = {};
var itemsList = [];
x = [{"id":"item1","val":"foo"},
{"id":"item2","val":"bar"},
{"id":"item1","val":"baz"},
{"id":"item1","val":"bez"}];
for (var i = 0; i < x.length; i++) {
var item = x[i];
if (!itemsObj[item.id]) {
itemsObj[item.id] = item;
itemsList.push(item);
}
}
console.log(itemsList);
This is late but I did something like the following:
let MyArray = [];
MyArray._PushAndRejectDuplicate = function(el) {
if (this.indexOf(el) == -1) this.push(el)
else return;
}
MyArray._PushAndRejectDuplicate(1); // [1]
MyArray._PushAndRejectDuplicate(2); // [1,2]
MyArray._PushAndRejectDuplicate(1); // [1,2]
This is how I would do it in pure javascript.
var x = [{"id":"item1","val":"Items"},{"id":"item1","val":"Items"},{"id":"item1","val":"Items"}];
function unique(arr, comparator) {
var uniqueArr = [];
for (var i in arr) {
var found = false;
for (var j in uniqueArr) {
if (comparator instanceof Function) {
if (comparator.call(null, arr[i], uniqueArr[j])) {
found = true;
break;
}
} else {
if (arr[i] == uniqueArr[j]) {
found = true;
break;
}
}
}
if (!found) {
uniqueArr.push(arr[i]);
}
}
return uniqueArr;
};
u = unique(x, function(a,b){ return a.id == b.id; });
console.log(u);
y = [ 1,1,2,3,4,5,5,6,1];
console.log(unique(y));
Create a very readable solution with lodash.
x = _.unionBy(x, [new Item(clickId, obj)], 'id');
let x = [{id:item1,data:value},{id:item2,data:value},{id:item3,data:value}]
let newEle = {id:newItem,data:value}
let prev = x.filter(ele=>{if(ele.id!=new.id)return ele);
newArr = [...prev,newEle]

Combine array items from different properties in a JavaScript object

I'm trying create a function that will iterate an object of arrays, and return one array that concatenates each element from one array to each element in the other arrays:
Object like so:
kitchen = {
food: [".bacon",".bananas"],
drinks: [".soda",".beer"],
apps: ['.fritters','.wings']
}
Desired returned array:
[
".bacon.soda",".bacon.beer",
".bananas.soda",".bananas.beer",
".bacon.fritters",".bacon.wings",
".bananas.fritters",".bananas.wings",
".soda.fritters",".soda.wings",
".beer.fritters",".beer.wings"
]
I'm having difficulty wrapping my brain around how to accomplish this. One thought I had was to create another object and create a hash where each array item becomes a property and then looping through so I have something like:
newObj = {
".bacon": [".soda",".beer",".fritters",".wings"]
".bananas": [".soda",".beer"...etc]
etc...
}
then loop through each prop, concatenating the property on each array element into a new array? Not sure if that's overkill though?
Plain JS is fine, but if you have a coffeescript solution as well that would be great too.
Thanks
Here's a solution that makes use of CoffeeScript syntax (since you asked for a CoffeeScript answer and then deleted that request?):
kitchen =
food: [".bacon",".bananas"]
drinks: [".soda",".beer"]
apps: ['.fritters','.wings']
allGroups = Object.keys(kitchen).map (key) -> kitchen[key]
allValues = []
allGroups.forEach (group, i) ->
otherValues = Array.prototype.concat.apply [], allGroups.slice(i + 1)
group.forEach (v1) -> otherValues.forEach (v2) -> allValues.push(v1 + v2)
console.log(allValues)
Here is the plain JS version:
var kitchen = {
food: [".bacon", ".bananas"],
drinks: [".soda", ".beer"],
apps: ['.fritters', '.wings']
}
var allGroups = Object.keys(kitchen).map(function(key) {
return kitchen[key];
});
var allValues = []
allGroups.forEach(function(group, i) {
var otherValues = Array.prototype.concat.apply([], allGroups.slice(i + 1));
group.forEach(function(v1) {
otherValues.forEach(function(v2) {
allValues.push(v1 + v2);
});
});
});
console.log(allValues)
Try this:
var result = [];
var keys = Object.keys(kitchen);
for (var i = 0; i < keys.length; i++) {
kitchen[keys[i]].forEach(function(ingred1) {
for (var j = i+1; j < keys.length; j++) {
kitchen[keys[j]].forEach(function(ingred2) {
result.push(ingred1 + ingred2);
});
}
});
}
console.log(result);

Concatenate to access an object property [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Dynamic object property name
I want to dynamically generate access to an object's property.
If I try to access mydata[i].val.name I get somename.
If I try it like mydata[i] + bar[j] (where bar[j] === '.val.name') it fails.
How do I dynamically create something like this? So that I can access any property of an object using a user generated value?
Some code:
If I have an object I want to be able to iterate through its properties, gathering the ones I am interested in. Ideally I would like something like the following:
var processData = function (data, keys, values) {
var returnData = [], i, j, k;
var parsedData = JSON.parse(data);
var keys = keys || null;
var values = values || null;
var datalen = parsedData.length;
for (i = 0; i < datalen; i++) {
returnData[i] = {};
for(j = 0; j< keys.length; j++){
for(k = 0; k < values.length; k++){
returnData[i][keys[j]] = parsedData[i] + values;
}
}
}
return returnData;
};
and then use it like:
var keys = ["foo","bar"];
var values = [".val.name", ".val.date"];
processData(data, keys, values);
But this does not work and in console I see foo="[object Object].val.name" rather than the expected foo="ACME Industries".
If you want to stick to your pattern of constructing the subscript as a string with dots in it you have to roll your own lookup function, like so:
function descend(object, sub) {
var handle = object,
stack = sub.split('.'),
history = [],
peek;
while (handle[stack[0]]) {
if (peek) {
history.push(peek);
}
peek = stack.shift();
handle = handle[peek];
}
if (stack.length > 0) {
history.push(peek);
throw "Traversal error, could not descend to '" + stack.join('.') + "' from '" + history.join('.') + "'.";
}
return handle;
}
var x = {
a: {
b: {
c: 15
},
d: 4
}
};
console.log(descend(x, "a"));
console.log(descend(x, "a.b"));
console.log(descend(x, "a.b.c"));
console.log(descend(x, "a.d"));
function processData(data, keys, values) {
if (keys.length !== values.length) {
throw "Mismatched keys and value lookups";
}
var i,
len = keys.length,
gathered = {},
k,
scratch,
v;
for (i = 0; i < len; i += 1) {
k = descend(data, keys[i]);
scratch = values[i].split('.');
scratch.shift();
v = descend(k, scratch.join('.'));
gathered[keys[i]] = v;
}
return gathered;
}
var data = {
foo: {
val: {
name: "ACME Industries"
}
},
bar: {
val: {
date: (new Date())
}
}
};
var keys = ["foo","bar"];
var values = [".val.name", ".val.date"];
processData(data, keys, values);
Please note: this will not be nearly as performant as coding without this style of lookup.
If you try:
new Object() + '.john.doe'
It will concatenate as a string, so you’ll get "[object Object].john.doe".
You should create a function that can handle dynamic property names instead (and there are plenty of those). You also might want to loose the ".foo.bar" syntax as a string (unless you plan to use eval()) and work solely with arrays instead.
If I understand correctly you need to use
mydata[i]["val"]["name"]
So, I'd use something like this:
var result =getItemByValuesPath(myData[i],values);
alert(result);
function getItemByValuesPath(item, values)
{
var result = item;
var vals = values.split(".");
for(var j=0; j<values.length; j++)
{
if(result==undefined)
{
return null;
}
result = result[values[j]];
}
}

Categories