ES6: Merge two arrays into an array of objects - arrays

I have two arrays that I want to merge together to one array of objects...
The first array is of dates (strings):
let metrodates = [
"2008-01",
"2008-02",
"2008-03",..ect
];
The second array is of numbers:
let figures = [
0,
0.555,
0.293,..ect
]
I want to merge them to make an object like this (so the array items match up by their similar index):
let metrodata = [
{data: 0, date: "2008-01"},
{data: 0.555, date: "2008-02"},
{data: 0.293, date: "2008-03"},..ect
];
So far I do this like so: I create an empty array and then loop through one of the first two arrays to get the index number (the first two arrays are the same length)... But is there an easier way (in ES6)?
let metrodata = [];
for(let index in metrodates){
metrodata.push({data: figures[index], date: metrodates[index]});
}

The easiest way is probably to use map and the index provided to the callback
let metrodates = [
"2008-01",
"2008-02",
"2008-03"
];
let figures = [
0,
0.555,
0.293
];
let output = metrodates.map((date,i) => ({date, data: figures[i]}));
console.log(output);
Another option is to make a generic zip function which collates your two input arrays into a single array. This is usually called a "zip" because it interlaces the inputs like teeth on a zipper.
const zip = ([x,...xs], [y,...ys]) => {
if (x === undefined || y === undefined)
return [];
else
return [[x,y], ...zip(xs, ys)];
}
let metrodates = [
"2008-01",
"2008-02",
"2008-03"
];
let figures = [
0,
0.555,
0.293
];
let output = zip(metrodates, figures).map(([date, data]) => ({date, data}));
console.log(output);
Another option is to make a generic map function which accepts more than one source array. The mapping function will receive one value from each source list. See Racket's map procedure for more examples of its use.
This answer might seem the most complicated but it is also the most versatile because it accepts any number of source array inputs.
const isEmpty = xs => xs.length === 0;
const head = ([x,...xs]) => x;
const tail = ([x,...xs]) => xs;
const map = (f, ...xxs) => {
let loop = (acc, xxs) => {
if (xxs.some(isEmpty))
return acc;
else
return loop([...acc, f(...xxs.map(head))], xxs.map(tail));
};
return loop([], xxs);
}
let metrodates = [
"2008-01",
"2008-02",
"2008-03"
];
let figures = [
0,
0.555,
0.293
];
let output = map(
(date, data) => ({date, data}),
metrodates,
figures
);
console.log(output);

If you use lodash, you can use zipWith + ES6 shorthand propery names + ES6 Arrow functions for a one-liner, otherwise see #noami's answer.
const metrodata = _.zipWith(figures, metrodates, (data, date)=> ({ data, date }));

Related

using array for URLSearchParams in vue3

i want to append key and value of array , using for axos request
here is the array
const
schedule = ref({
"userId" : 13,
"sunday" : ["mornig","afternoon","nigh"],
"monday" : ["afternoon","nigh"],
"wednesday" : ["mornig","afternoon"]
})
to append manuallya i can do like this
params.append("userId",data.value.userId)
params.append("sunday[0]",data.value.sunday[0])
params.append("sunday[1]",data.value.sunday[1])
params.append("sunday[2]",data.value.sunday[2])
params.append("monday[0]",data.value.monday[0])
params.append("monday[1]",data.value.monday[1])
params.append("wednesday[0]",data.value.wednesday[0])
params.append("wednesday[1]",data.value.wednesday[1])
but this will be problim if length of the schedule time l (morning,night ...) unknown
i do like this
let i = 0
for(let j in data.value){
console.log(j+$[i++])
}
and also loop using for in and for of , but none of them are success
You "just" need to do a nested iteration. Loop through object, and if any value is an array, loop through the array. Here's an example code to flatten the dataset. Just note that instead of flattenData(schedule) you'd need to pass the ref's value with flattenData(schedule.value).
const schedule = {
userId: 13,
sunday: ["mornig", "afternoon", "nigh"],
monday: ["afternoon", "nigh"],
wednesday: ["morning", "afternoon"],
};
function flattenData(data) {
const o = {};
Object.keys(data).forEach((dataKey) => {
if (Array.isArray(data[dataKey])) {
data[dataKey].forEach(
(_, nestedArrayIndex) =>
(o[`${dataKey}[${nestedArrayIndex}]`] =
data[dataKey][nestedArrayIndex])
);
} else {
o[dataKey] = data[dataKey];
}
});
return o;
}
// show flattened data
console.log(flattenData(schedule));
// prepare params
const params = new URLSearchParams("");
// populate
Object.entries(flattenData(schedule)).forEach(([k,v]) => params.append(k, v))
// result:
console.log(params.toString())

How to return objects that have matching value when comparing to a separate array

In my state I have an object called foodLog which holds all entries a user enters with one of the keys being foodSelectedKey and I'm trying to return all entries that have a matching value from that key with a different array called foodFilter.
However, this doesn't work and errors out saying foodLog.filter() isn't a function - I've looked this up and it's because it's an Object (I think). Any help would be greatly appreciated!
state = {
// log food is for the logged entries
foodLog: {},
// used for when filtering food entries
foodFilter: [],
};
findMatches = () => {
let foodLog = this.state.foodLog;
let foodFilter = this.state.foodFilter;
let matched = foodLog.filter((item) => {
return foodLog.foodsSelectedKey.map((food) => {
return foodFilter.includes(food);
});
});
};
I guess the reason behind the error Is not a function is that the object can not be looped. By that it means you can not iterate an object with differend variables inside, if it has no index to be iterated like an array. The same goes for map(), find() and similar functions which MUST be run with arrays - not objects.
As far as I understand you have an object named foodLog which has an array named foodsSelectedKey. We need to find intersected elements out of foodFilter with the array. This is what I came up with:
state = {
// log food is for the logged entries
foodLog: {
foodsSelectedKey: [
{ id: 1, name: "chicken" },
{ id: 2, name: "mashroom" }
]
},
// used for when filtering food entries
foodFilter: [
{ id: 1, name: "chicken" },
{ id: 2, name: "orange" }
]
};
findMatches = () => {
let foodLog = this.state.foodLog;
let foodFilter = this.state.foodFilter;
let matched = foodLog.foodsSelectedKey.filter((key) =>
{
for (let i=0; i<foodFilter.length;i++){
if(foodFilter[i].name===key.name)
return true
}
return false;
}
);
return matched;
};
The Output is filtered array, in this case, of one element only:
[{
id: 1
name: "chicken"
}]
In order to check the output - run console.log(findMatches()). Here is the CodeSandbox of the solution. (check console at right bottom)

why add curly braces to the argument 'people' here [duplicate]

I have been reading about Destructuring assignment introduced in ES6.
What is the purpose of this syntax, why was it introduced, and what are some examples of how it might be used in practice?
What is destructuring assignment ?
The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
- MDN
Advantages
A. Makes code concise and more readable.
B. We can easily avoid repeated destructing expression.
Some use cases
1. To get values in variable from Objects,array
let obj = { 'a': 1,'b': {'b1': '1.1'}}
let {a,b,b:{b1}} = obj
console.log('a--> ' + a, '\nb--> ', b, '\nb1---> ', b1)
let obj2 = { foo: 'foo' };
let { foo: newVarName } = obj2;
console.log(newVarName);
let arr = [1, 2, 3, 4, 5]
let [first, second, ...rest] = arr
console.log(first, '\n', second, '\n', rest)
// Nested extraction is possible too:
let obj3 = { foo: { bar: 'bar' } };
let { foo: { bar } } = obj3;
console.log(bar);
2. To combine an array at any place with another array.
let arr = [2,3,4,5]
let newArr = [0,1,...arr,6,7]
console.log(newArr)
3. To change only desired property in an object
let arr = [{a:1, b:2, c:3},{a:4, b:5, c:6},{a:7, b:8, c:9}]
let op = arr.map( ( {a,...rest}, index) => ({...rest,a:index+10}))
console.log(op)
4. To create a shallow copy of objects
let obj = {a:1,b:2,c:3}
let newObj = {...obj}
newObj.a = 'new Obj a'
console.log('Original Object', obj)
console.log('Shallow copied Object', newObj)
5. To extract values from parameters into standalone variables
// Object destructuring:
const fn = ({ prop }) => {
console.log(prop);
};
fn({ prop: 'foo' });
console.log('------------------');
// Array destructuring:
const fn2 = ([item1, item2]) => {
console.log(item1);
console.log(item2);
};
fn2(['bar', 'baz']);
console.log('------------------');
// Assigning default values to destructured properties:
const fn3 = ({ foo="defaultFooVal", bar }) => {
console.log(foo, bar);
};
fn3({ bar: 'bar' });
6. To get dynamic keys value from object
let obj = {a:1,b:2,c:3}
let key = 'c'
let {[key]:value} = obj
console.log(value)
7. To build an object from other object with some default values
let obj = {a:1,b:2,c:3}
let newObj = (({d=4,...rest} = obj), {d,...rest})
console.log(newObj)
8. To swap values
const b = [1, 2, 3, 4];
[b[0], b[2]] = [b[2], b[0]]; // swap index 0 and 2
console.log(b);
9. To get a subset of an object
9.1 subset of an object:
const obj = {a:1, b:2, c:3},
subset = (({a, c}) => ({a, c}))(obj); // credit to Ivan N for this function
console.log(subset);
9.2 To get a subset of an object using comma operator and destructuring:
const object = { a: 5, b: 6, c: 7 };
const picked = ({a,c}=object, {a,c})
console.log(picked); // { a: 5, c: 7 }
10. To do array to object conversion:
const arr = ["2019", "09", "02"],
date = (([year, day, month]) => ({year, month, day}))(arr);
console.log(date);
11. To set default values in function. (Read this answer for more info )
function someName(element, input,settings={i:"#1d252c", i2:"#fff",...input}){
console.log(settings.i)
console.log(settings.i2)
}
someName('hello', {i:'#123'})
someName('hello', {i2:'#123'})
12. To get properties such as length from an array, function name, number of arguments etc.
let arr = [1,2,3,4,5];
let {length} = arr;
console.log(length);
let func = function dummyFunc(a,b,c) {
return 'A B and C';
}
let {name, length:funcLen} = func;
console.log(name, funcLen);
It is something like what you have can be extracted with the same variable name
The destructuring assignment is a JavaScript expression that makes it possible to unpack values from arrays or properties from objects into distinct variables. Let's get the month values from an array using destructuring assignment
var [one, two, three] = ['orange', 'mango', 'banana'];
console.log(one); // "orange"
console.log(two); // "mango"
console.log(three); // "banana"
and you can get user properties of an object using destructuring assignment,
var {name, age} = {name: 'John', age: 32};
console.log(name); // John
console.log(age); // 32
The De-structured assignment of Javascript is probably an inspiration drawn from Perl language.
This facilitates reuse by avoid writing getter methods or wrapper functions.
One best example that I found very helpful in particular was on reusing functions that return more data than what is required.
If there is a function that returns a list or an array or a json, and we are interested in only the first item of the list or array or json,
then we can simply use the de-structured assignment instead of writing a new wrapper function to extract the interesting data item.

How to apply search filter on 2 different arrays in Ionic 2?

I have applied search filter on a array using this code in my listproduct.ts
if (val && val.trim() != '') {
this.names = this.names.filter((names) => {
return (names.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
}
Note that this filter is applied on names array. I wish this filter should also work on catg and pservice named arrays too.
How can I achieve filter result on multiple arrays?
You can create another bigArray which is the concatenation of your three arrays using js concat function :
var bigArray = this.names.concat(this.catg, this.pservice);
and call your filter on that bigArray.
var val = "test";
this.names = ["abc", "test123", "test"];
this.catg = ["qsd", "azetest"];
this.pservice = ["another test !", "tss"];
this.bigArray = this.names.concat(this.catg, this.pservice);
// here, bigArray contains all values of the three arrays (abc,test123,test,qsd,azetest,another test !,tss)
if (val && val.trim() != '') {
this.bigArray = this.bigArray.filter((names) => {
return (names.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
// here, bigArray contains only filtered values of the three arrays (test123,test,azetest,another test !)
Here is a working Plunker
If you need to keep them as separate arrays, and cannot concat them, you could do something like this:
let names = ["Andy", "Alex", "Corbyn", "Eric" ];
let catg = ["Adventure", "Action", "Comedy", "SciFi"];
let pservice = ["Example", "Service", "Allo"]
let val = "a";
[names, catg, pservice] = [names, catg, pservice].map(array => {
return array.filter((item) => {
return (item.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
});
console.log(names);
console.log(catg);
console.log(pservice);

What is the Best way to loop over an array in scala

I'm new to scala and I'm trying to refactor the below code.I want to eliminate "index" used in the below code and loop over the array to fetch data.
subgroupMetricIndividual.instances.foreach { instanceIndividual =>
val MetricContextListBuffer: ListBuffer[Context] = ListBuffer()
var index = 0
contextListBufferForSubGroup.foreach { contextIndividual =>
MetricContextListBuffer += Context(
entity = contextIndividual,
value = instanceIndividual(index).toString
)
index += 1
}
}
For instance, if the values of variables are as below:
contextListBufferForSubGroup = ("context1","context2")
subgroupMetricIndividual.instances = {{"Inst1","Inst2",1},{"Inst3","Inst4",2}}
Then Context should be something like:
{
entity: "context1",
value: "Inst1"
},
{
entity: "context2",
value: "Inst2"
},
{
entity: "context1",
value: "Inst3"
},
{
entity: "context2",
value: "Inst4"
}
Note:
instanceIndividual can have more elements than those in contextListBufferForSubGroup. We must ignore the last extra elements in instanceIndividual in this case
You can zip two lists into a list of tuples and then map over that.
e.g.
subgroupMetricIndividual.instances.foreach { instanceIndividual =>
val MetricContextListBuffer = contextListBufferForSubGroup.zip(instanceIndividual).map {
case (contextIndividual, instanceIndividualIndex) => Context(
entity = contextIndividual,
value = instanceIndividualIndex.toString
)
}
}
If Context can be called like a function i.e. Context(contextIndividual, instanceIndividualIndex.toString) then you can write this even shorter.
subgroupMetricIndividual.instances.foreach { instanceIndividual =>
val MetricContextListBuffer = contextListBufferForSubGroup
.zip(instanceIndividual.map(_.toString)).map(Context.tupled)
}
Without knowing your exact datatypes, I'm mocked up something which is probably close to what you want, and is slightly more functional using maps, and immutable collections
case class Context(entity:String, value:String)
val contextListBufferForSubGroup = List("context1","context2")
val subgroupMetricIndividualInstances = List(List("Inst1","Inst2",1),List("Inst3","Inst4",2))
val result: List[Context] = subgroupMetricIndividualInstances.map { instanceIndividual =>
contextListBufferForSubGroup.zip(instanceIndividual) map { case v: (String, String) =>
Context(
entity = v._1,
value = v._2
)
}
}.flatten

Resources