How to copy a variable arrray from another arrray in javascripts - javascript

I have an array as below:
const arr = [
{
title: 's4',
value: '124'
},
{
title: 's2',
value: '121'
},
{
title: 's3',
value: '122'
}
];
and I want to create a new another array copy from the old array same as below:
const arrCopy = [
{
value: '124'
},
{
value: '121'
},
{
value: '122'
}
];
then my code as below:
var arrCopy = [...arr,arr.value]
but it has a problem, so anyone help me, thanks.

Just as in the comment above you can use awesome Javascript functions, in this case, you would like to use the map function of your array to map every item of the array as you like.
const arrayMapped = yourArray.map(item => {
value: item.value
})
Here is another way using Javascript Destructuring, you just ask with properties would you like from the JS Object, in this case, you just like the value property.
const arrayMapped = yourArray.map(( { value } ) => ( { value } ))
How Array.map works
How Object Destructuring works

You can simply use Array.map, as it returns a new array with the required value.
const newArr = arr.map(element => ({ value: element.value }))
console.log(newArr);
For references : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

If you are allowed to import a library. Ramda has a lot of functions to work with arrays.
For your specific question, project would do the job.
import R from "ramda";
R.project(["value"], arr) //return equals arrCopy

Related

How can I "unstack" my JSON data in d3.js?

I have data in a JSON array that looks like this:
[{"TEACHER":3.7},{"STUDENT":1.9}]
My desired output is a JSON array that looks like this:
var statements = [
{
name: "TEACHER",
value: 3.7
},
{
name: "STUDENT",
value: 1.9
}
];
How can I "unstack" the data I have to add the variable labels like I want?
This is what I came up with. There might be a more elegant way to do this though.
var x = [{"TEACHER":3.7},{"STUDENT":1.9}];
console.log(unstack(x));
function unstack(stacked){
var unstacked = [];
stacked.forEach((element) => {
unstacked.push({
name: Object.keys(element)[0],
value: Object.values(element)[0]
});
});
return unstacked;
}
Is it the only key your original object has? If that's the case, you can use the only item Object.keys() or Object.entries() return. If there are other attributes you could look for a match in the key and process it accordingly.
const input = [{"TEACHER":3.7},{"STUDENT":1.9}];
const output = [];
input.forEach(item => {
const key = Object.keys(item)[0];
output.push({name: key, value: item[key]});
});
console.log(output);

ES6 way - Get unique values from a nested array by key

trying to improve my JS chops.
Is there a cleaner way to retrieve the property value from the array below, by key, from a nested object, removing duplicates and sorting them alphabetically?
Here's what I have:
getObjectValues(array, key){
var unique = [];
array.forEach(function(item){
item[key].forEach(function(value){
if (unique.indexOf(value) < 0) {
unique.push(value)
}
})
});
return unique.sort();
},
example array of object:
[
{ name: 'hello', value: ['a','b','c']},
{ name: 'hello', value: ['a','b','c']},
{ name: 'hello', value: ['a','b','c']}
]
expected output should be an array:
var array = ['a','b','c']
You could just use a Set, and add all the items to it:
let arr = [
{ name: 'hello', value: ['a','b','c']},
{ name: 'hello', value: ['a','b','c']},
{ name: 'hello', value: ['a','b','c']}
]
console.log(
Array.from(
new Set(
arr.reduce(
(carry, current) => [...carry, ...current.value],
[]
)
)
).sort()
)
If you need something concise, you may go as simple as that:
make use of Set to get rid of duplicates
employ Array.prototype.flatMap() (with slight touch of destructuring assignment) to extract value items from within all objects into single array
const src = [{name:'hello',value:['c','b','d']},{name:'hello',value:['e','b','c']},{name:'hello',value:['f','a','e']}],
result = [...new Set(src.flatMap(({value}) => value))].sort()
console.log(result)
.as-console-wrapper{min-height:100%;}
If you need something really fast, you may do the following:
use Array.prototype.reduce() to turn your array into Set of unique records (looping through value items with Array.prototype.forEach and doing Set.prototype.add())
spread resulting Set into array and .sort() that
const src = [{name:'hello',value:['c','b','d']},{name:'hello',value:['e','b','c']},{name:'hello',value:['f','a','e']}],
result = [...src.reduce((acc,{value}) =>
(value.forEach(acc.add, acc), acc), new Set())].sort()
console.log(result)
.as-console-wrapper{Min-height:100%;}

Filter a javascript tree without mutating the original array

I'm working on a react project where I need to filter an array of objects without mutating the original array
const array = [{
name: 'bar',
children: [{
name: 'foo',
children: [{
name: 'baz123',
}, {
name: 'baz',
}]
}]
}, {
name: 'shallowKey'
}, {
name: 'abc'
}];
For example, I want to only filter the concerned object and its children.
This is the jsfiddle
function filterData(data) {
var r = data.filter(function(o) {
if (o.children) o.children = filterData(o.children);
return o.name.length === 3;
})
return r;
}
I tried that function from a stackoverflow question, but is there a way to use that same functionality without mutating the data. Thanks
If you don't have any prototypes or functions involved within the objects a simple way to copy is to stringify original and parse it back to object
var r= JSON.parse(JSON.stringify(data)).filter(...
Array .filter() already creates a new array, you just need to fix the part where the o.children is mutated. To do that you could use .map() and simply copy all fields using Object.assign() or object spread and just assign children as the result passed through the same filter function:
function filterData(data) {
return data
.filter(obj => obj.name.length === 3) // filter array first
.map(obj => ({ // then re-map to new objects
...obj, // copy shallow fields
children: obj.children && filterData(obj.children) // filter children
}));
}
You can create a copy of your original array using a spread operator or Object.assign() function.
const arrayCopy= [...array] //spread operator
const arrayCopy = Object.assign({}, array);
Otherwise as Aaron suggested, using filter(), map(), reduce() function always returns a new array without mutating your original array.

Converting flat array to Id and Name object array using Lodash

let states = ["Georgia","California","FL","TX","MA","NJ"];
How do I convert the states array into Id and Name array collection using lodash.
Is there a way to convert the array in below format ( image shown below):
You don't really need lodash to do that.
let states = ["Georgia","California","FL","TX","MA","NJ"];
let result = states.map((item) => {
return {
id: item,
name: item}})
console.log(result)
You do pretty much the same with lodash
import _ from 'lodash';
result = _.map(states, (item) => {
return {
id: item,
name: item}})
let states = ["Georgia","California","FL","TX","MA","NJ"];
const newObj = [];
_.each(states, state => newObj.push({ id: state, name: state }));
console.log(newObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
_.each performs a function on each item of an Array. With that you can create a new object for each state and push that into a new Array. Note: this could also be accomplished with JavaScript's built in .map.
----- UPDATE -----
Why did I make this complicated many years ago?
const states = ["Georgia","California","FL","TX","MA","NJ"];
const newObj = states.map(state => ({ id: state, name: state }));
console.log(newObj);
No need to use lodash, just map through the array and return a new object for each item in the array.

Functional Javascript map with index

I need a functional approach to solve a very basic problem, the problem with list indexes, let me write an example with React and ramda that shows the need of an index.
const R = require('ramda');
const array = ["foo", "bar", "foobar"];
// Need to put them in a nice html li ?
// this works with a warning that you
// need a unique key to each item.
const renderList = R.map( item => <li>{item}</li> );
// we can solve it like that.
const mapIndexed = R.addIndex(R.map)
const renderListIndexed = mapIndexed((item, id) => <li key={id}>{item}</li>
All of that is cool, but I'm pretty sure the use of an indexed map is not a functional approach, let me know if I'm wrong.
I'm not sure what is Ramda doing since I'm not familiar with React stuff, but if you need an index for elements of your array, you can use basic Array.map function.
const array = ["foo", "bar", "foobar"];
array.map(function(item, index) {
return {
item: item,
id: index
}
});
which will give you an array of objects structured as:
[{ id: 0, item: "foo" }, { id: 1, item: "bar" }, { id: 2, item: "foobar" }]
Hope this helps!
Look at addIndex. There are some very good reasons why Ramda does not include it by default, but this function will mix it in for you.
Try
const renderList = R.addIndex(R.map)( item => <li>{item}</li> );

Categories

Resources