let a = [{
a:1,
b:3,
c:[1, 2, 6]
},
{
a:3,
b:10,
c:[2, 5, 4]
},
{
a:4,
b:3,
c:[7, 12, 6]
},
{
a:4,
b:12,
}]
let b = [2, 6]
I want to return an array from a object that matches from b arrays.
I used :
lodash.forEach(b , (value)=>{
lodash.filter(a, {c: value})
}
but this doesnt work . I tried to simple my code for better underestanding.
You could filter the array by looking if the values of b are included in c.
var a = [{ a: 1, b: 3, c: [1, 2, 6] }, { a: 3, b: 10, c: [2, 5, 4] }, { a: 4, b: 3, c: [7, 12, 6] }, { a: 4, b: 12 }],
b = [2, 6],
result = a.filter(({ c = [] }) => b.some(v => c.includes(v)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
For getting only items who match completely, you could use Array#every instead of Array#some.
var a = [{ a: 1, b: 3, c: [1, 2, 6] }, { a: 3, b: 10, c: [2, 5, 4] }, { a: 4, b: 3, c: [7, 12, 6] }, { a: 4, b: 12 }],
b = [2, 6],
result = a.filter(({ c = [] }) => b.every(v => c.includes(v)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
To find objects with c contain all b values you can use Array.filter() and Array.every():
let a = [{ a: 1, b: 3, c: [1, 2, 6] }, { a: 3, b: 10, c: [2, 5, 4] }, { a: 4, b: 3, c: [7, 12, 6] }, { a: 4, b: 12 }];
let b = [2, 6]
console.log(a.filter(({c = []}) => b.every(v => c.includes(v))));
if you want common values use Array.some() instead of Array.every():
let a = [{ a: 1, b: 3, c: [1, 2, 6] }, { a: 3, b: 10, c: [2, 5, 4] }, { a: 4, b: 3, c: [7, 12, 6] }, { a: 4, b: 12 }];
let b = [2, 6]
console.log(a.filter(({c = []}) => b.some(v => c.includes(v))));
I believe this is what you want - you can do it in pure JS:
let a = [{
a:1,
b:3,
c:[1, 2, 6]
},
{
a:3,
b:10,
c:[2, 5, 4]
},
{
a:4,
b:3,
c:[7, 12, 6]
},
{
a:4,
b:12,
}]
let b = [2, 6]
let c = a.filter(({ c = [] }) => c ? b.some(n => c.includes(n))) : false;
console.log(c);
Assuming you want to filter objects in array a that have atleast one value in c which exists in b array.
You can use Array.filter, Array.some & Array.includes
let a=[{a:1,b:3,c:[1,2,6]},{a:3,b:10,c:[2,5,4]},{a:4,b:3,c:[7,12,6]},{a:4,b:12,}];
let b=[2,6];
let result = a.filter(v => v.c && v.c.some(v1 => b.includes(v1)));
console.log(result);
You can use lodash as follows
let a=[{a:1,b:3,c:[1,2,6]},{a:3,b:10,c:[2,5,4]},{a:4,b:3,c:[7,12,6]},{a:4,b:12,}];
let b=[2,6];
let result = _.filter(a, v => v.c && _.some(v.c, c => _.includes(b,c)));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Related
Let's say we have an array of object:
var obj = [{a: 1, b: 2, c: 3, d: 4, e: 5 },{a: 6, b: 7, c:
8, d: 9, e: 0 }];
and we want to delete key c,e from both of the objects.
How can it be done? One of the methods I found is:
['c', 'e'].forEach(e => delete obj[e]); //for object
Is there any other way so we don't have to use double for loop.
One way to do it is to use .map() together with object destructuring:
var obj = [
{ a: 1, b: 2, c: 3, d: 4, e: 5 },
{ a: 6, b: 7, c: 8, d: 9, e: 0 },
];
var newObj = obj.map(({ c, e, ...rest }) => rest);
console.log(newObj)
This will create a new array with new objects which contain all of the other keys except for c and e.
You have 2 options to resolve it:
By using object destructuring: map(({ a,b,c,d,e }) => ({a,b,d})
Enhance option 1 by using using [Rest parameters] { c, e, ...rest }
Object destructuring like below
const obj = { a: 1, b: 2, c: 3, d: 4, e: 5 } var {c, e} = obj; // c = 3, e = 5
With option 2, you will have c,e implicit name and the remaining items named rest. After that, you just need to get rest items.
Option 1
var obj =
[
{ a: 1, b: 2, c: 3, d: 4, e: 5 },
{ a: 6, b: 7, c: 8, d: 9, e: 0 },
];
console.log(obj.map(({ a,b,c,d,e }) => ({a,b,d})));
Option 2
var obj =
[
{ a: 1, b: 2, c: 3, d: 4, e: 5 },
{ a: 6, b: 7, c: 8, d: 9, e: 0 },
];
console.log(obj.map(({ c, e, ...rest }) => rest));
// ...rest: the same as `a,b,d`
I have fairly lot of data in this form
A B C D
-------
1 2 3 4
5 6 7 8
9 1 2 3
represented using javascript types as :
df = {A: [1,5,9], B: [2,6,1], C: [3,7,2], D:[4,8,3]}
I want to convert this into this form:
[{A:1, B:2, C:3, D:4}, {A:5, B:6, C:7, D:8}, {A:9, B:1, C:2, D:3}]
I tried implementing it as:
keyes = ["A", "B", "C", "D"]
getrow = (i) => Object.assign( ...keyes.map((k) => ({[k]: df[k][i]})))
df.A.map( (x,j) => getrow(j))
But this is slow for the size of the table I have. Is there any faster way to do this?
You could use reduce and forEach loops to create array of objects.
const df = {
A: [1, 5, 9],
B: [2, 6, 1],
C: [3, 7, 2],
D: [4, 8, 3]
}
const result = Object.keys(df).reduce((r, k) => {
df[k].forEach((e, i) => {
if (!r[i]) r[i] = {}
r[i][k] = e;
})
return r;
}, [])
console.log(result)
Or maybe for better performance you can go with the for loops.
const df = {
A: [1, 5, 9],
B: [2, 6, 1],
C: [3, 7, 2],
D: [4, 8, 3]
}
const result = [];
for (let key in df) {
for (let i = 0; i < df[key].length; i++) {
if (!result[i]) result[i] = {}
result[i][key] = df[key][i]
}
}
console.log(result)
You could take two for loops, and check the existence of the object at a certain index. Then assign the value to the property.
This version is faster than the use of array methods.
var data = { A: [1, 5, 9], B: [2, 6, 1], C: [3, 7, 2], D: [4, 8, 3] },
result = [],
key, values,
i;
for ([key, values] of Object.entries(data)) {
for (i = 0; i < values.length; i++) {
if (!result[i]) result[i] = {};
result[i][key] = values[i];
}
}
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have list array object like:
let arr = [
{ a: 1, b: 2, c: 3, d: 4 },
{ a: 2, b: 3, c: 4, d: 5 },
{ a: 5, b: 6, c: 7, d: 8 }
]
and after using reduce()
// get props **b, c**
let arr_result = arr.reduce( ... )
// arr_result = [
// { b: 2, c: 3 },
// { b: 3, c: 4 },
// { b: 6, c: 7 }
// ]
use map.
let arr = [{
a: 1,
b: 2,
c: 3,
d: 4
},
{
a: 2,
b: 3,
c: 4,
d: 5
},
{
a: 5,
b: 6,
c: 7,
d: 8
}
]
const output = arr.map(({b, c}) => ({b, c}));
console.log(output);
You can use ES6(and beyond)'s object destructuring.
const arr = [
{ a: 1, b: 2, c: 3, d: 4 },
{ a: 2, b: 3, c: 4, d: 5 },
{ a: 5, b: 6, c: 7, d: 8 }
]
const res = arr.map(obj => {
const { b, c } = obj;
return { b, c };
});
console.log(res);
Since you asked to achieve this using reduce, here is the way. Pass an empty array as thisArg & inside reduce callback function create an object with required key and push it to the accumulator
let arr = [{
a: 1,
b: 2,
c: 3,
d: 4
},
{
a: 2,
b: 3,
c: 4,
d: 5
},
{
a: 5,
b: 6,
c: 7,
d: 8
}
];
let newArr = arr.reduce(function(acc, curr) {
acc.push({
b: curr.b,
c: curr.c
})
return acc;
}, [])
console.log(newArr)
If you want to use reduce:
const arr = [{a:1,b:2,c:3,d:4},{a:2,b:3,c:4,d:5},{a:5,b:6,c:7,d:8}];
const res = arr.reduce((a, { b, c }) => (a.push({ b, c }), a), []);
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }
It's honestly a lot easier with map:
const arr = [{a:1,b:2,c:3,d:4},{a:2,b:3,c:4,d:5},{a:5,b:6,c:7,d:8}];
const res = arr.map(({ b, c }) => ({ b, c }));
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }
I have an array which can be nested multiple times. However, always two arrays with two entries each are at the end of each "nesting". I always need the two entries from the two arrays at the end of each nesting returned.
Here is an example:
const arr = [
[
[1, 2], [3, 4]
], [
[5, 6], [7, 8]
], [
[
[9, 10], [11, 12]
], [
[14, 15], [16, 17]
]
]
];
Here is the expected result:
const return1 = [
{ a: 1, b: 2 },
{ a: 3, b: 4 }
];
const return2 = [
{ a: 5, b: 6 },
{ a: 7, b: 8 }
];
const return3 = [
{ a: 9, b: 10 },
{ a: 11, b: 12 }
];
const return4 = [
{ a: 13, b: 14 },
{ a: 15, b: 16 }
];
Everything I find online is how to reduce an n-nested array to a flat array, something like this:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
You could map with an iterative and recursive approach while checking nested arrays.
var array = [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[[9, 10], [11, 12]], [[14, 15], [16, 17]]]],
result = array.reduce(function iter(r, a) {
return r.concat(Array.isArray((a[0] || [])[0])
? a.reduce(iter, [])
: [a.map(([a, b]) => ({ a, b }))]
);
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
With custom recursive function:
var arr = [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[[9, 10], [11, 12]], [[14, 15], [16, 17]]]],
result = [],
get_pairs = function(arr, r){
arr.forEach(function(v){
if (Array.isArray(v)) {
if (!Array.isArray(v[0])) {
var o = {a: v[0], b: v[1]};
(!r.length || r[r.length-1].length==2)? r.push([o]) : r[r.length-1].push(o);
} else {
get_pairs(v, r);
}
}
});
};
get_pairs(arr, result);
console.log(result);
Spent to much time in this. However, here is a very messy looking code.
There is this recursive function that checks if a given array is in the form [[number, number],[number, number]]. If so, it adds an object to the variable returnArray that we are knowingly mutating.
If it is not in the form, we just check for the items inside the array.
const arrInput = [
[[1, 2], [3, 4]],
[[5, 6], [7, 8]],
[
[[9, 10], [11, 12]],
[[14, 15], [16, 17]],
],
];
function mapArrayToObj(arr, returnArray = []) {
if (arr.length === 2 && typeof arr[0][0] === "number" &&
typeof arr[0][1] === "number" && typeof arr[1][0] === "number" &&
typeof arr[1][1] === "number") {
returnArray.push([
{ a: arr[0][0], b: arr[0][1] },
{ a: arr[1][0], b: arr[1][1] }
]);
} else {
arr.forEach((item) => { mapArrayToObj(item, returnArray); });
}
return returnArray;
}
console.log(mapArrayToObj(arrInput));
With the lodash library, I'd like to be able to pluck multiple values into a multi-dimensional array, along the lines of:
var arr = [{ a: 2, b: 3, c: 4 }, { a: 1, b: 4, c: 2 }];
_.pluck(arr, ['a', 'c']) --> [[2, 4], [1, 2]]
Is this possible?
Thanks.
There is no pluck on multiple keys, but you can do this:
_.map(['a', 'c'], function(path) {
return _.pluck(arr, path);
});
This will return values grouped by key.
Edit:
_.mpluck = function(collection, paths) {
return _.zip(
_.map(paths, function(path) {
return _.pluck(collection, path);
})
);
}
var arr = [{ a: 2, b: 3, c: 4 }, { a: 1, b: 4, c: 2 }];
_.mpluck(arr, ['a', 'c']) --> [[2, 4], [1, 2]]
this will replace each object by an array of the specified keys.
Without lodash:
function mpluck(collection, paths) {
return collection.map(function(obj) {
return paths.map(function(path) {
return obj[path];
});
});
}
Solution without lodash:
function pluck(arr, k) {
return arr.reduce(function (r, a) {
r.push(k.reduce(function (rr, aa) {
rr.push(a[aa]);
return rr;
}, []));
return r;
}, []);
}
var arr = [{ a: 2, b: 3, c: 4 }, { a: 1, b: 4, c: 2 }],
x = pluck(arr, ['a', 'c']);
document.write('<pre>' + JSON.stringify(x, 0, 4) + '</pre>');