Create multidimensional arry without identifier - javascript

I'd like to use a multidimensional arry in JS. The array looks like this:
var name = {
abc: {
0: 'a',
1: 'b',
2: 'c'
}
};
This works like a charm. But is it possible to create the same array without the numbers? Like this:
var name = {
abc: {
'a',
'b',
'c'
}
};
I still need the same access to it (e.q. name['abc'][1] = b)

Use an actual array instead of an object for abc?
var name = {
abc: [
'a',
'b',
'c'
]
};

Related

Create new object out of huge array of objects

I retrieve a huge array from the server (contains 2000+ objects). the structure of this array is like this:
const arr = [
{code: 'A', text:'blabla', codeParent:'-'},
{code: 'B', text:'blabla', codeParent:'-'},
{code: 'C', text:'blabla', codeParent:'-'},
{code: 'D', text:'blabla', codeParent:'-'},
{code: '01', text:'blabla', codeParent:'B'},
{code: '02', text:'blabla', codeParent:'C'},
{code: '03', text:'blabla', codeParent:'D'},
{code: '04', text:'blabla', codeParent:'A'},
{code: '05', text:'blabla', codeParent:'A'},
{code: '06', text:'blabla', codeParent:'B'},
...
]
The object that I want to make looks like this:
const obj = {
A: [array of all object with codeParent 'A'],
B: [array of all object with codeParent 'B'],
C: [array of all object with codeParent 'C'],
D: [array of all object with codeParent 'D']
}
Does anyone know the best way to get this result?
Assuming a couple things about your output that weren't entirely clear from your explanation, but appear to be the case from your sample output:
The output is collated by the codeParent property
You are skipping items that have codeParent: '-'
Then, you can just iterate through the big array and populate the output object as you go:
let result = {};
for (item of arr) {
let parent = item.codeParent;
if (parent !== '-') {
let destArray = obj[parent];
// if no array yet for this code, create one
if (!destArray) {
destArray = [];
obj[parent] = destArray;
}
// add the new item to the destination array
destArray.push(item);
}
}
console.log(result);
Some people will prefer to use .reduce() for this:
let result = arr.reduce((obj, item) => {
let parent = item.codeParent;
if (parent !== '-') {
let destArray = obj[parent];
// if no array yet for this code, create one
if (!destArray) {
destArray = [];
obj[parent] = destArray;
}
// add the new item to the destination array
destArray.push(item);
}
return obj;
}, {});
Note, each loop has slightly more code because I'm trying to only have to look up obj[item.codeParent] once for each iteration rather than multiple times and also trying to only look up the codeParent propery in item.codeParent once too. You could do it with less code like this and slightly less efficient:
let result = arr.reduce((obj, item) => {
if (item.codeParent !== '-') {
if (!obj[item.codeParent]) {
obj[item.codeParent] = [];
}
obj[item.codeParent].push(item);
}
return obj;
}, {});
Note that this looks up obj[item.codeParent] 2 or 3 times in every iteration whereas the previous two versions look it up 1 or 2 times.

Is there a way to search through specific keys within an object and then log the results?

I'm trying to work out how to search through an object to check if there is a match with the search value. From there I want to list which objects had a match.
For this example I want to search through name1 and name2 and see if either of them have an options value of C. If there is a match then list which objects matched the search. If the search value was for A it would then show up only name1.
I've tried setting up the myObject with data but I'm not sure how to loop through the object, check specific values of the options key to compare them with the search.
let myObject = {
name1: {
title: 'Mr',
options: ['A', 'B', 'C'],
},
name2: {
title: 'Mrs',
options: ['C', 'D', 'E'],
}
};
function myFunction() {
var optionSearch = 'C';
console.log(optionSearch);
for (var i = 0; i < myObject.length; i++) {
if (myObject[i].options == optionSearch)
console.log(myObject[i] + ' is equal to optionSearch');
else {
console.log('No match');
}
}
}
myFunction();
Objects don't have a default length property. So, you can't use for loop with numerical indexes. You can instead use for...in to loop through the object like this:
let myObject = {
name1: {
title: 'Mr',
options: ['A', 'B', 'C'],
},
name2: {
title: 'Mrs',
options: ['C', 'D', 'E']
}
};
function myFunction(optionSearch) {
for (var key in myObject) {
if (myObject[key].options.includes(optionSearch))
console.log(key + ' has : ' + optionSearch)
}
}
myFunction('C')
myFunction('A')
You could also filter the keys which have an options value which includes the given option
let myObject = {name1:{title:'Mr',options:['A','B','C'],},name2:{title:'Mrs',options:['C','D','E'],}};
function getKeys(obj, option) {
return Object.keys(obj).filter(k => obj[k].options.includes(option))
}
console.log(getKeys(myObject, 'C')) // [ "name1", "name2"]
console.log(getKeys(myObject, 'A')) // [ "name1" ]
var myObject = {
name1: {
title: 'Mr',
options: ['A', 'B', 'C'],
},
name2: {
title: 'Mrs',
options: ['C', 'D', 'E'],
}
};
function myFunction(optionSearch) {
console.log(optionSearch);
for(var i in myObject) {
if (myObject[i].options.indexOf(optionSearch) >= 0)
console.log(i + ' is equal to optionSearch');
else {
console.log('No match');
}
}
}
This should work:
Object.keys(myObject)
.filter((key) => {
return myObject[key].options.includes(optionSearch)
})

delete property with sequential index in object

i have an object like below:
item = {
0: 'A',
1: 'B',
2: 'C',
3: 'D'
}
For e.g., if i would like to delete '1' from the item object and after it was deleted, '2' and '3' should auto minus 1 and become object below:
item = {
0: 'A',
1: 'C',
2: 'D'
}
Is it possible to achieve this with object beside using array?
Omit the key you don't want, convert to array using Object.values(), and then convert back to object by spreading to an empty object:
const item = {
0: 'A',
1: 'B',
2: 'C',
3: 'D'
}
const result = { ...Object.values(_.omit(item, 1)) }
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Or you can create a function that uses rest params:
const fn = (key, { [key]: _, ...rest }) => ({ ...Object.values(rest) })
const item = {
0: 'A',
1: 'B',
2: 'C',
3: 'D'
}
const result = fn(1, item)
console.log(result)
Use a delete statement
delete item["1"];
You can use an array for removing and for re-indexing purpose.
let item = {
0: 'A',
1: 'B',
2: 'C',
3: 'D'
};
// get values as an array
let arr = Object.values(item);
// remove element at index 1
arr.splice(1, 1);
// extract array to an object
item = {
...arr
};
console.log(item);
Here another solution in case you don't want to rely in third party plugins. Lodash is quite a heavy library as well.
var deleteObj = ({data, index}) => {
var objSize = Object.keys(data).length
if (index > objSize -1) return data
var count = index;
delete data[count];
count = count+1;
while (count < objSize){
data[count-1] = data[count];
count = count+1;
}
delete data[count-1];
return data;
}
deleteObj({data: {0: "A", 1: "B", 2: "C", 3: "D", 4: "E", 5: "F"}, index: 0});
Or else you can use lodash's filter directly on object (actually you can) to remove unnecessery items and then produce an array in one step, and then just use object spread operator to build back the resultant object.
Example:
let o = {"0":"A","1":"B","2":"C","3":"D"},
res = {..._.filter(o, (v, k) => k!=1)};
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

How we can merge arrays with uniq values using Underscore.js?

If i've two array like
a= [{ name: 'a', name: 'b' }]
b= [c, d, b, e]
I want the result to be like
[
{ 'name': 'a' },
{ 'name': 'b' },
{ 'name': 'c' },
{ 'name': 'd' },
{ 'name': 'e' }
]
But do not want to repeatedly check like first array convert using _.map() and after merge using _.union() or other type then check _.uniq() through but I need all if possible then make as a short layer.
To do this with Backbone.Collection, you can leverage the model parse function as well as providing the parse: true option on instantiation. By specifying a model idAttribute, duplicate models are avoided. Note: I used lodash here for some type checking and array merge.
var a = [{name: 'a'}, {name: 'b'}];
var b = ['c', 'd', 'b', 'e'];
var Coll = Backbone.Collection.extend({
model: Backbone.Model.extend({
idAttribute: 'name',
parse: function(resp, opts) {
var modelData = resp;
if (_.isString(resp)) {
modelData = { name: resp };
}
return modelData;
}
})
});
// then on initialize
var data = _.union(a, b);
var coll = new Coll(data, {parse: true});
console.log(JSON.stringify(coll.toJSON()));
// yields
"[{"name":"a"},{"name":"b"},{"name":"c"},{"name":"d"},{"name":"e"}]"
// alternatively, you can choose not merge the data to start
// and instead either pass some at initialize and then
// some with a coll.set later, or all with set
// Note: set call still needs parse:true as well as remove:false
var coll = new Coll(a, {parse: true});
coll.set(b, {parse: true, remove: false});
console.log(JSON.stringify(coll.toJSON()));
// yields
"[{"name":"a"},{"name":"b"},{"name":"c"},{"name":"d"},{"name":"e"}]"

How to create a javascript function that output a list of object with a list of the object's property?

I have a piece of javascript that looks like the following
var set = [{
name: 'a',
property1: '',
property2: '',
},
{
name: 'b',
property1: '',
property2: '',
},
{
name: 'c',
property1: '',
property2: '',
}];
Since property1 and property2 are both empty for all objects, I want to automate this such that I only need to keep track of the name. Something like:
namelist = ['a', 'b', 'c'];
magicFunction(namelist);
that magicFunction can return that set I mentioned above. I am very new to javascript, if you think this is too rudimentary for stackoverflow, please give me a few keywords so I know what I should be searching for. Thanks!
You can use map
To get set from nameList
var namelist = ['a', 'b', 'c'];
var set = namelist.map(function(e) { return { name: e, property1: 0, property2: 0 }});
function magicFunction(arr) {
return arr.map(function(e) {
return {
name: e,
property1: 0,
property2: 0
}
});
}
var namelist = ['a', 'b', 'c'];
set = magicFunction(namelist);
console.log(set);
document.getElementById('output').innerHTML = JSON.stringify(set, 0, 2);
<pre id="output"></pre>
Sounds to me like you need to use a constructor function and then 'construct' or return objects from that and store in your set:
// quick array
var someArray = ['a', 'b', 'c'];
// define array for output
var set = [];
// constructor to create the objects
function something(name, param1, param2) {
this.name = name;
this.property1 = param1;
this.property2 = param2;
}
// run through the quick array and build the objects with the constructor - push into 'set'
var magicFunction = function(arrayName) {
for (var i = 0; i < arrayName.length; i++) {
set.push( new something( someArray[i] ) );
}
}
magicFunction(someArray);
console.log(set);
jsFiddle
One solution :
/* instead of console.log */
function log(val){
document.write('<pre>' + JSON.stringify( val , null , ' ') + '</pre>');
};
function magicFunction( listOfNames ) {
return listOfNames.map(function( currentValue ){
return {
name : currentValue ,
property1 : '',
property2 : '',
};
})
};
var namelist = ['a', 'b', 'c' , 'd' , 'e' , 'f'];
log( magicFunction(namelist) );
function magicFunction(nameList){
var set = [];
for(var i = 0; i<nameList.length;i++){
var temp = new Object();
temp.property1='';
temp.property2='';
temp.name=nameList[i];
set.push(temp);
}
return set;
}

Categories

Resources