Javascript: Convert a list of objects to an associative array - javascript

I'm looking for a way to take an array of JavaScript objects and get an associative array of those objects keyed by some attribute.
For example, given this array of objects:
var data = [
{'id': 100, name: 'bob', foo: 'bar'},
{'id': 200, name: 'john', foo: 'qux'}
];
I want to be able to look up each object by its id, so I want an object like this:
var new_data = {
100: {name: 'bob', foo: 'bar'},
200: {name: 'john', foo: 'qux'}
}
// now I can use new_data[200] to access `john`
While I'm sure it's easy enough to construct a new object and then iterate over each object in the original array and append a new key:value pair to new object, I was wondering if there was a more concise way of doing it.

In ES6:
Object.assign({}, ...data.map(({id, name, foo}) => ({[id]: {name, foo}})))
This maps each object in the input into a single-property object with the id as key, then spreads those into parameters to Object.assign which will glue them together for you.
Or,
construct a new object and then iterate over each object in the original array and append a new key:value pair to new object
You can do essentially what you just said but in relatively concise form using reduce:
data.reduce((result, {id, name, foo}) => {
result[id] = {name, foo};
return result;
}, {})

You may try this:
var data = [
{'id': 100, name: 'bob', foo: 'bar'},
{'id': 200, name: 'john', foo: 'qux'}
];
data.reduce(function(p, c){
p[c.id] = {name:c.name, foo: c.foo};
return p;
}, {});

Here is a solution using Array maps:
var data = [{
'id': 100,
name: 'bob',
foo: 'bar'
}, {
'id': 200,
name: 'john',
foo: 'qux'
}];
var new_data = {};
// Iterate over data
data.map(obj => {
// Create new object from old
new_data[obj.id] = {
'name': obj.name,
'foo': obj.foo
}
});
console.log(new_data);

In ES5:
working JSBIN: https://jsbin.com/qudeze/edit?js,console
var data = [
{'id': 100, name: 'bob', foo: 'bar'},
{'id': 200, name: 'john', foo: 'qux'}
];
var new_data = {
100: {name: 'bob', foo: 'bar'},
200: {name: 'john', foo: 'qux'}
};
var y = data.reduce(function(result, next) {
result[next.id] = {name: next.name, foo: next.foo};
return result;
}, {});
console.log(y);

Your code should be go like this....
<script type="text/javascript">
var data = [
{'id': 100, name: 'bob', foo: 'bar'},
{'id': 200, name: 'john', foo: 'qux'}
];
var new_data = {};
for(var i=0; i<data.length; i++){
var element = {};
element["name"] = data[i].name;
element["foo"] = data[i].foo;
new_data[data[i].id] = element;
}
console.log(JSON.stringify(new_data));

I don't think we could use map method. Because our output is not an array but an object. We could use each method to help us. Here is a sample code:
var data = [
{'id': 100, name: 'bob', foo: 'bar'},
{'id': 200, name: 'john', foo: 'qux'}
];
var result = {};
data.forEach(function(item){
var key = item.id;
//remove id from item
delete item.id;
result[key] = item;
});
console.log(result);
Note, this solution will modify the original array. If you don't want change the original one, just copy one.

Related

Delete multiple objects in an array by id

I have a main array of objects with each object having some key/values as well as a "id" key with 1,2,3,4,5, etc
Now I have another array representing just id's (like [2,3])
I want to use this array to delete objects from the main array...so in this case, objects from the main array having id's 2 & 3 should be deleted
While I am aware of findBy(id), I am not sure if that can be used to delete multiple objects at once.
You can use filter. In the filter callback function check if the id is also there in id array by using includes
let idArr = [1, 2]
let obj = [{
id: 1,
name: 'abc'
},
{
id: 2,
name: 'abc'
},
{
id: 3,
name: 'abc'
},
{
id: 4,
name: 'abc'
}
];
let data = obj.filter(item => !idArr.includes(item.id));
console.log(data);
console.log(obj)
using filter might work well here. you could write something like:
var newArray = oldArray.filter(object => !ids.includes(object.id))
You can do it, like this:
[2,3].forEach(key => {
delete object[key];
})
You can use filter method for this.
Ex:
let id = 2;
let list = [{
Id: 1,
Name: 'a'
}, {
Id: 2,
Name: 'b'
}, {
Id: 3,
Name: 'c'
}];
let lists = list.filter(x => {
return x.Id != id;
})
console.log(lists);
Assuming you want to delete items from the original array by entirely removing the element from the array (and you don't want to get a new array), you can take advantage of
Array.splice
let idArr = [1, 2];
let obj = [{
id: 1
},
{
id: 2
},
{
id: 3
},
{
id: 4
}
];
for (let id of idArr) {
// look for the element by its id.
const objIdRef = obj.find(i => i.id === id);
// if it actually exists, splice it.
objIdRef && obj.splice(obj.indexOf(objIdRef), 1);
}
console.log(obj);
If the obj array is big, you might want to make a map from it before processing the id array, so that the complexing is reduced to O(1) when the delete process begins.
Perhaps This is what you want:
var arr= [{id:1, name: "foo"}, {id:2, name: "bar"}, {id:3, name:"not to be deleted"}];
var idsToDelete = [1, 2];
var res = arr.map((i, idx)=>{
return arr[idx] = idsToDelete.includes(i.id)? undefined : arr[idx]
}).filter(i=>i)
console.log(res)
You can try Lodash.js functions _.forEach() and _.remove()
let valuesArr = [
{id: 1, name: "dog"},
{id: 2, name: "cat"},
{id: 3, name: "rat"},
{id: 4, name: "bat"},
{id: 5, name: "pig"},
];
let removeValFromIndex = [
{id: 2, name: "cat"},
{id: 5, name: "pig"},
];
_.forEach(removeValFromIndex, (indi) => {
_.remove(valuesArr, (item) => {
return item.id === indi.id;
});
})
console.log(valuesArr)
/*[
{id: 1, name: "dog"},
{id: 3, name: "rat"},
{id: 4, name: "bat"},
]; */
Don't forget to clone (_.clone(valuesArr) or [...valuesArr]) before mutate your array

Check and get data from an array in JavaScript

I have an object:
var Obj1 = {id: 1, name: 'Apple'}
And an array object:
var ArrObj = [ {id: 1, name: 'Apple', 'eat': 'rice}, {'id: 2', 'name': 'Banana'}]
How do I check Obj1.id in ArrObj? And I want the result to be: { id:1, name: 'Apple', 'eat':'rice'}
You can use Array.find():
var Obj1 = {id: 2, name: 'Banana'}
var ArrObj = [ {id: 1, name: 'Apple', 'eat': 'rice'}, {'id': 2, 'name': 'Banana'}];
var res = ArrObj.find(({id}) => id === Obj1.id );
console.log(res);
You can also use array destructuring way like:
var Obj1 = {id: 2, name: 'Banana'}
var ArrObj = [ {id: 1, name: 'Apple', 'eat': 'rice'}, {'id': 2, 'name': 'Banana'}];
var res = ArrObj.find(({id}) => id === Obj1.id);
console.log(res);
You could also use the filter function like this:
let result = ArrObj.filter(obj => {
return obj.id == Obj1.id
})
Documentation is here: Array.prototype.filter()
all right!
you can also add array and get it by code :
var obj = '{ "name" : "amr" , "age" : "16"}';
var obj1 = JSON.parse(obj);
alert("yourname is : "+obj1.name+" , your age is "+obj1.age);
// it get name > amr and age > 16
it's very easy :)

Using template literal for dynamic property in ReactJS

My failed attempt:
temp.map((obj,i) => ({
obj[`person${++i}`] = obj.person.name
})
I want to produce something like this
[{id:324, person1:'mike'},{id:23, person2:'jane'}]
But I'm stuck on making the property dynamic with concatenation using template literal string.
Issue with you code is, you are directly returning the data by using
() => ({....})
and there you are using obj[...] that is not a valid key.
map return the a new array so store the result in a new variable, if you want to modify the same array then better to use forEach.
Check this snippet:
let arr = [{id: 10, name: 'A'}, {id: 20, name: 'B'}];
let newArr = arr.map((el,i) => ({
id: el.id,
[`name${i+1}`]: el.name
}));
console.log('new array', newArr);
Modifying the same data using forEach:
let arr = [{id: 10, name: 'A'}, {id: 20, name: 'B'}];
arr.forEach((el,i) => {
el[`person${i+1}`] = el.name;
})
console.log('modified array', arr);
This should do it:
var myInput = ["John", "Jane", "Steven", "Alice"];
var myOutput = myInput.map ((name, index) => {
var out = {};
out[`person${index}`] = name;
return out;
}); // myOutput is [{person1:"John"}, {person2:"Jane"} ... etc.
map creates a new array rather than modifying the existing one. The values of the array are made out of the return values of the function, so if you want your values to be objects, you must create new objects and then assign your properties to them.
How about this?
describe("sample test", () => {
it("Dynamic property in ES6", () => {
const temp = [
{ id: 324, person: { name: "mike" } },
{ id: 23, person: { name: "jane" } }
];
console.log(
temp.map((obj, i) => ({
id: obj.id,
[`person${i + 1}`]: obj.person.name
}))
);
});
});
Output:
[ { id: 324, person1: 'mike' }, { id: 23, person2: 'jane' } ]

JavaScript: replacing object keys with an array

I'm new to JS and experimenting the things. I have following object:
var data = {'name': 'john', 'old': 18, 'place': 'USA'}
How can I switch the keys of this object with the following array?
var array = ['First Name', 'age', 'country']
To look following:
{'First Name': 'john', 'age': 18, 'country': 'USA'}
The only way to rename a key of an object is to assign the value of the old key to the new key and then delete the old key
Object[ new_key ] = Object[ old_key ];
delete Object[ old_key ];
Another way is to create a completely new object (with the new keys), assign the values to the new keys and then delete the old object.
var array = ['First Name', 'age', 'country'];
var data = {'name': 'john', 'old': 18, 'place': 'USA'};
var keys = Object.keys(data);
var newData = {};
for (var a in array) {
//using new obj
newData[array[a]] = data[keys[a]];
//editing same obj
data[array[a]] = data[keys[a]];
delete data[keys[a]];
}
console.log(data);
console.log(newData);
var array = ['First Name', 'age', 'country'];
var list = [
{ 'name': 'john 1', 'old': 18, 'place': 'USA' },
{ 'name': 'john 2', 'old': 19, 'place': 'USB' },
{ 'name': 'john 3', 'old': 20, 'place': 'USC' },
];
var newList = [];
for (var item in list) {
var newData = {};
for (var a in array) {
newData[array[a]] = list[item][Object.keys(list[item])[a]];
}
newList.push(newData);
}
console.log(newList);
You can use Object.assign(), Object.entries(), .map(), spread element and computed properties to assign the property name to a new object having value to to current index of property, value within iteration, set identifier for original object to result of Object.assign() call
let array = ['First Name', 'age', 'country']
let data = {'name': 'john', 'old': 18, 'place': 'USA'}
data = Object.assign({}, ...Object.entries(data)
.map(([, prop], index) => ({[array[index]]: prop})));
console.log(data);
Rather than switching the object keys; which cannot be done and you'd have to delete keys and add the new one, you could simply create a new object with the desired keys:
var data2 = {};
data2['First Name'] = data.name;
data2.age = data.old;
data2country = data.place;
You could use an object with the replacement keys and iterate it for changing the keys.
var data = { name: 'john', old: 18, place: 'USA' },
newKeys = { name: 'First Name', old: 'age', place: 'country' };
Object.keys(newKeys).forEach(function (k) {
data[newKeys[k]] = data[k];
delete data[k];
});
console.log(data);
var data = {'name': 'john', 'old': 18, 'place': 'USA'}
var ary = ['First Name', 'age', 'country']
// create key-value pairs array
var obj_entries = Object.entries(data)
var new_data =ary.reduce((acc, value, idx)=>{
acc[value]=obj_entries[idx][1];
return acc;
}, {})
console.log(new_data)
Maybe a functional approach

How search two arrays and find if there is a match?

I have an array :
[{name:'blah',id:1},{name:'blah2',id:3}]
I have another array :
[{type:'blah',uid:3435},{type:'blah2',uid:3}]
I want to end up with :
[{newname:'blah2',uidid:3}]
You can see I want to match the two based on a mapping of id=uid. Really struggling to find a way to do this in js. I have underscore installed.
You could build a hash table with the first array and use it in the iteration of the second array.
var array1 = [{ name: 'blah', id: 1 }, { name: 'blah2', id: 3 }],
array2 = [{ type: 'blah', uid: 3435 }, { type: 'blah2', uid: 3 }],
hash = Object.create(null),
match = [];
array1.forEach(function (a) {
hash[a.id] = a;
});
array2.forEach(function (a) {
hash[a.uid] && match.push({ newname: a.type, uidid: a.uid });
});
console.log(match);
Since you are wanting an array with an object that uses different key names, something like this will work. It is also simple to read and to understand without any complex syntax or logic.
var arr1 = [{name: 'blah', id: 1}, {name: 'blah2', id: 3}];
var arr2 = [{type: 'blah', uid: 3435}, {type: 'blah2', uid: 3}];
var arr3 = [];
arr1.forEach(function(obj1, i) {
arr2.forEach(function(obj2) {
if (obj1.id == obj2.uid) {
arr3.push({newname: obj1.name, uidid: obj1.id})
}
})
});
console.log(arr3);

Categories

Resources