I am trying to join an array of dates and values to an array of dates, without filtering out the extra dates. The LinqJS reference here is pretty confusing on how I would actually go about using the join. The question here did not help much either.
Edit:
Join documentation here: .html#Join
It looks like I need help sorting out how to get the join to be an outer
and not an inner
join so it includes null/undefined values.
Say I have two arrays:
Array 1:
[
'2017-02-10',
'2017-02-11',
'2017-02-12',
'2017-02-13',
'2017-02-20',
'2017-02-21',
'2017-02-22',
'2017-02-23',
'2017-02-24',
'2017-02-25',
'2017-02-26',
'2017-02-27'
]
Array 2:
[
{ date: '2017-02-10', value: 5 },
{ date: '2017-02-12', value: 8 },
{ date: '2017-02-13', value: 13 },
{ date: '2017-02-21', value: 14 },
{ date: '2017-02-24', value: 11 },
{ date: '2017-02-27', value: 7 }
]
I want to join them so I get this as my result (-
for undefined
):
[
'5',
-,
'8',
'13',
-,
'14',
-,
-,
'11',
-,
-,
'7'
]
My current syntax:
Enumerable.from(array1).join(array2, '$', '$.date', "outer, inner => inner.value").toArray()
This results in an array of the values, but the results are still inner joined, and it filters out what might be the null/undefined
items.
How can I do this? How does the join syntax work for LinqJS?
I am trying to join an array of dates and values to an array of dates, without filtering out the extra dates. The LinqJS reference here is pretty confusing on how I would actually go about using the join. The question here did not help much either.
Edit:
Join documentation here: https://svschmidt.github.io/linqjs/Collection.html#Join
It looks like I need help sorting out how to get the join to be an outer
and not an inner
join so it includes null/undefined values.
Say I have two arrays:
Array 1:
[
'2017-02-10',
'2017-02-11',
'2017-02-12',
'2017-02-13',
'2017-02-20',
'2017-02-21',
'2017-02-22',
'2017-02-23',
'2017-02-24',
'2017-02-25',
'2017-02-26',
'2017-02-27'
]
Array 2:
[
{ date: '2017-02-10', value: 5 },
{ date: '2017-02-12', value: 8 },
{ date: '2017-02-13', value: 13 },
{ date: '2017-02-21', value: 14 },
{ date: '2017-02-24', value: 11 },
{ date: '2017-02-27', value: 7 }
]
I want to join them so I get this as my result (-
for undefined
):
[
'5',
-,
'8',
'13',
-,
'14',
-,
-,
'11',
-,
-,
'7'
]
My current syntax:
Enumerable.from(array1).join(array2, '$', '$.date', "outer, inner => inner.value").toArray()
This results in an array of the values, but the results are still inner joined, and it filters out what might be the null/undefined
items.
How can I do this? How does the join syntax work for LinqJS?
Share Improve this question edited Apr 26, 2017 at 15:11 Nina Scholz 387k26 gold badges363 silver badges413 bronze badges asked Apr 25, 2017 at 19:29 Douglas GaskellDouglas Gaskell 10.1k12 gold badges80 silver badges135 bronze badges 9- You can not join both arrays because their content differs. You can transform them to a final new array though. – MaxZoom Commented Apr 25, 2017 at 19:32
- Do you need to use Linq or vanilla js is OK too ? – Vololodymyr Commented Apr 25, 2017 at 19:33
- I think you mean this library : github./SvSchmidt/linqjs , I prefer the look of github's readmes ;) – niceman Commented Apr 25, 2017 at 19:34
- @MaxZoom Can you explain why that is? I know you can select the keys you wish to join by with LinqJS, I just do not know how. – Douglas Gaskell Commented Apr 25, 2017 at 19:34
- First array is array of strings, while the second one contains objects. You need to transform the first array along the structure of the second one. – MaxZoom Commented Apr 25, 2017 at 19:36
2 Answers
Reset to default 5I'm not sure about LinqJS, but regular JS is more than capable of doing this.
There are a couple ways to go about it. The reduce()
, map()
, and sort()
functions are very Linq-esque and work well natively. (There is also filter()
and a number of others).
const dates = [
'2017-02-10',
'2017-02-11',
'2017-02-12',
'2017-02-13',
'2017-02-20',
'2017-02-21',
'2017-02-22',
'2017-02-23',
'2017-02-24',
'2017-02-25',
'2017-02-26',
'2017-02-27'
]
const data = [
{ date: '2017-02-10', value: 5 },
{ date: '2017-02-12', value: 8 },
{ date: '2017-02-13', value: 13 },
{ date: '2017-02-21', value: 14 },
{ date: '2017-02-24', value: 11 },
{ date: '2017-02-27', value: 7 }
];
const result = dates
.map(date => ({ date, value: '-' }))
.concat(data)
.filter(({ date, value }) => !(data.find(d => d.date === date) && value === '-'))
.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
console.log(result);
const justValues = Object.keys(result).map(key => result[key].value);
console.log(justValues);
You could use GroupJoin
Correlates the elements of two sequences based on equality of keys and groups the results. The default equality parer is used to pare keys.
for a LEFT OUTER JOIN and specify the wanted value and use DefaultIfEmpty
Returns the elements of the specified sequence or the specified value in a singleton collection if the sequence is empty.
with the wanted replacement, if null.
var dates = ['2017-02-10', '2017-02-11', '2017-02-12', '2017-02-13', '2017-02-20', '2017-02-21', '2017-02-22', '2017-02-23', '2017-02-24', '2017-02-25', '2017-02-26', '2017-02-27'],
values = [{ date: '2017-02-10', value: 5 }, { date: '2017-02-12', value: 8 }, { date: '2017-02-13', value: 13 }, { date: '2017-02-21', value: 14 }, { date: '2017-02-24', value: 11 }, { date: '2017-02-27', value: 7 }],
result = Enumerable
.From(dates)
.GroupJoin(
values,
'',
'$.date',
't, u => ({ date: t, value: u.Select("$.value").DefaultIfEmpty("-").ToString() })')
.ToArray();
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare./ajax/libs/linq.js/2.2.0.2/linq.js"></script>
ES6
var dates = ['2017-02-10', '2017-02-11', '2017-02-12', '2017-02-13', '2017-02-20', '2017-02-21', '2017-02-22', '2017-02-23', '2017-02-24', '2017-02-25', '2017-02-26', '2017-02-27'],
values = [{ date: '2017-02-10', value: 5 }, { date: '2017-02-12', value: 8 }, { date: '2017-02-13', value: 13 }, { date: '2017-02-21', value: 14 }, { date: '2017-02-24', value: 11 }, { date: '2017-02-27', value: 7 }],
result = Enumerable
.From(dates)
.GroupJoin(
values,
'',
'$.date',
(t, u) => ({
date: t,
value: u.Select("$.value").DefaultIfEmpty("-").ToString()
}))
.ToArray();
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare./ajax/libs/linq.js/2.2.0.2/linq.js"></script>