Basic programming - array of objects to a multi-dimensional object - javascript

I've been stuck on this for hours.
I have a list of objects:
const myCompanyList = [
{name: 'coca-cola', size: 'big', color: 'red'},
{name: 'my-cola', size: 'small', color: 'purple'},
{name: 'pepsi', size: 'big', color: 'blue'}
];
I need to get it into this format:
myJson = {
companies: {
big: {
coca-cola: {color: 'red'},
pepsi: {color: 'blue'}
},
small: {
my-cola: {color: 'purple'}
}
}
}
I've tried doing this:
wrapperObject = {};
innerObject = {};
for each object in myCompanyList {
innerObject[object.size] = { object.name : {color: object.color}}
}
but the object[name] bit overwrites. How can I write this so I can dynamically get names on each object/map level? Do I need to make another inner object/map to dynamically write the names?
I've tried writing this in Java but I ended up with 5 dimensional maps and it didn't work, so I just wondered if there was something simple I'm missing - answers in Java, javascript or pseudocode thanks.

You can use Array.reduce() to create a map, Try the following :
let myCompanyList = [{name: "coca-cola", size: "big", color: "red"}, {name: "my-cola", size: "small", color: "purple"},{name: "pepsi", size: "big", color:"blue"}];
let result = {};
result.companies = myCompanyList.reduce((a,curr)=>{
a[curr.size] = a[curr.size] || {};
a[curr.size][curr.name] = {"color" : curr.color};
return a;
},{});
console.log(result);

Related

pie() does not accept an array of objects

I have the following code:
public data = [
{
value: 61,
color: 'orange',
},
{
value: 29,
color: 'white',
},
{
value: 10,
color: 'blue',
},
];
public pie = d3
.pie()
.padAngle(0)
.value((d: any) => d.value);
const arcs = this.pie(this.data);
Which is basically the outcome of some of the various tutorials about building a donut chart with d3js.
Now I would like to add a custom interface for the items in the data array and also properly type the d parameter in the .value() function.
The problem is, that the #types/d3 package defines the expected data array as number[] and the d parameter as number.
Which means that I cannot use a custom interface for the data items. The typings package for D3 seems to be wrong in this case because all the tutorials I've read do it this way and the code works just fine.
What are my options in this case? Are there any workarounds? Can I override the typings that get into my way?
d3's pie accepts a generic just for that.
Here's how to solve this:
interface IData {
value: number;
color: string;
}
const data: IData[] = [
{
value: 61,
color: 'orange',
},
{
value: 29,
color: 'white',
},
{
value: 10,
color: 'blue',
},
];
const pie = d3
.pie<IData>()
.padAngle(0)
.value(d => d.value);
const arcs = pie(data);

How to locate an object within an array and replace it with a new object? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have an array like so:
[
{color: "blue"},
{color: "red", size: "large"},
{color: "green", size: "medium"}
]
Showing this how can I:
Find the object with a color of green
Replace that object with {color: "green", size: "x-large"}
You can use the function find and then modify the found object.
var array = [{color: "blue"}, {color: "red", size: "large"}, {color: "green", size: "medium"}],
found = array.find(({color}) => color === 'green');
if (found) found.size = 'x-large';
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use map array it will return array.
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
const arr= [
{color: "blue"},
{color: "red", size: "large"},
{color: "green", size: "medium"}
];
let result = arr.map(obj=>{
return obj.color=='green'? {color: "green", size: "x-large"}:obj;
})
console.log(result)
you can also use find
The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.
DEMO
const arr = [{
color: "blue"
}, {
color: "red",
size: "large"
}, {
color: "green",
size: "medium"
}];
let result = arr.find(v => v.color == 'green');
if (result) {
result.size = 'x-large';
}
console.log(arr)
If need to replace in the existing object you can use forEach and check for the color, else if need to return a new array you can use map function
var oldObj = [{
color: "blue"
},
{
color: "red",
size: "large"
},
{
color: "green",
size: "medium"
}
]
oldObj.forEach(function(item) {
if (item.color === 'green') {
item.size = 'x-medium';
}
});
console.log(oldObj)

Reduce returns undefined

I have an Array of Objects (Cars) :
var car = [
{speed: 20, color: "red"},
{speed: 5, color: "blue"},
{speed: 80, color: "yellow"},
{speed: 79, name: "orange"}
];
and a function that should return the fastest Car in the Array :
function getFastestCar(cars) {
cars.reduce(function (prevFastestCar,curFastestcar) {
if (curFastestcar.speed > prevFastestCar.speed) return curFastestcar;
else return prevFastestCar;
}, {speed: -Infinity, name: "test"});
};
After searching for a few hours I couldn´t find any solution why the function is returning undefined. I debugged the code and the function works perfectly fine, except in the last "step" it somehow replaces the fastest Car with undefined. I´m trying to understand the concept behind the reduce Method I know that there are easier ways to do this, but I´m curious why it is not working correctly.
You need to return the reduced value from the function.
return cars.reduce(..);
See the description of reduce.
Return value
The value that results from the reduction.
This is probably just personal preference, but I don't like using Array.reduce for tasks involving comparison. I think the following is much easier to follow:
const cars = [
{speed: 20, color: "red"},
{speed: 5, color: "blue"},
{speed: 80, color: "yellow"},
{speed: 79, name: "orange"}
];
function getFastestCar(cars) {
var fastestCar = {};
if (cars.length) {
cars.forEach(car => {
fastestCar = fastestCar.speed > car.speed ? fastestCar : car;
});
}
return fastestCar;
}
console.log(getFastestCar(cars));

Trying to recreate my console.log objects

I have a var that contains 4 objects that I see when I log it out in the console. But I have been trying to create the structure of this return variable (I want to sort it but first want to recreate the structure), but are failing at the last hurdle.
This is what the console puts out on original variable: [Object, Object, Object, Object]
This is what I get with created variable: [Object]
Here is my code to try and re-create it:
this.obj = [{items:[{code:'bravo',color:'blue',date:'2017-01-01',pos:'up'},
{code:'alpha',color:'blue',date:'2017-01-02',pos:'down'}],
color:'blue'}],
[{items:[{code:'bravo',color:'blue',date:'2017-01-01',pos:'up'},
{code:'alpha',color:'blue',date:'2017-01-02',pos:'down'}],
color:'green'}],
[{items:[{code:'bravo',color:'blue',date:'2017-01-01',pos:'up'},
{code:'alpha',color:'blue',date:'2017-01-02',pos:'down'}],
color:'red'}],
[{items:[{code:'bravo',color:'blue',date:'2017-01-01',pos:'up'},
{code:'alpha',color:'blue',date:'2017-01-02',pos:'down'}],
color:'yellow'}]
;
The first objects of both original and created are identical, but why does it not see my other three objects? If I add two [] around my code, it's sees all four, but then they have changed to arrays instead of objects...
Your code seems broken, if you order it in a readable way then it's clear:
var obj = [
{
items: [{
code: 'bravo', color: 'blue', date: '2017-01-01', pos: 'up'
}, {
code: 'alpha', color: 'blue', date: '2017-01-02', pos: 'down'
}],
color: 'blue'
}] // <=== the array ends here, but now you have this:
, [{ items: [{ ...
The compiler then does this:
var obj = [
{
items: [{
code: 'bravo', color: 'blue', date: '2017-01-01', pos: 'up'
}, {
code: 'alpha', color: 'blue', date: '2017-01-02', pos: 'down'
}],
color: 'blue'
}
], _a = (void 0)[0], _b = ....
As you can see it creates another variable (_a) to store the other data.
Got it working for anyone who wants to know:
this.obj = [{0:{items:[{code:'bravo',color:'blue',date:'2017-01-01',pos:'up'},
{code:'alpha',color:'blue',date:'2017-01-02',pos:'down'}],
color:'blue'}},
{1:{items:[{code:'bravo',color:'blue',date:'2017-01-01',pos:'up'},
{code:'alpha',color:'blue',date:'2017-01-02',pos:'down'}],
color:'green'}},
{2:{items:[{code:'bravo',color:'blue',date:'2017-01-01',pos:'up'},
{code:'alpha',color:'blue',date:'2017-01-02',pos:'down'}],
color:'red'}},
{3:{items:[{code:'bravo',color:'blue',date:'2017-01-01',pos:'up'},
{code:'alpha',color:'blue',date:'2017-01-02',pos:'down'}],
color:'yellow'}}]
;
}

Filter collection (array of objects) based on other array

I have the following problem. I wolud like to filter this fruitsCollection based on fruits array.
I would like to be the result was that, for example :
filteredFruits1 [ all fruits with the
exception of those which are in
fruitsToCut array
]
Example:
var fruitsToCut = [ 'egzotic', 'other'],
fruitsCollection = [ {name: papaya, type: 'egzotic'},
{name: orange, type: 'citrus'},
{name: lemon, type: 'citrus'}
]
Maybe some underscore function?
On a modern browser, you can use the native filter:
fruitsCollection.filter(function(fruit) {
return fruitsToCut.indexOf(fruit.type) === -1;
} );
Otherwise, you can use the underscore filter in pretty much the same way:
_.filter( fruitsCollection, function(fruit) {
return !_.contains(fruitsToCut, fruit.type);
} );
Also, your fruit names need to be quoted:
fruitsCollection = [ {name: 'papaya', type: 'egzotic'},
{name: 'orange', type: 'citrus'},
{name: 'lemon', type: 'citrus'}
];

Categories