Having some difficulty removing the row 0 in all my subarrays
Tried splice as well but can't seem to find a good example that remove values from subarrays.
Arr1
// This is how my main Arr1 looks like
(3) [Array(2), Array(2), ...]
0: (2) ["2021-07-06T00:00:00Z", {…}]
1: (2) ["2021-07-06T00:00:00Z", {…}]
...
// Which will have multiple subarrays when the main array is expanded
0: Array(2)
0: "2021-07-06T00:00:00Z"
1: {type: "meeting", id: "123"}
1: Array(2)
0: "2021-07-06T00:00:00Z"
1: {type: "call", id: "456"}
....
End result - Remove row 0, which is the date & time from each array and combine all of them together
0: {type: "meeting", id: "123"}
1: {type: "call", id: "456"}
Since you have nested arrays you will have to combine map and filter. Map to iterate the top level and filter or splice (depending on your logic) - on the sub to remove or filter out items.
topArray.map(subArray => subArray.filter(item => ...))
or
topArray.map(subArray => subArray.splice(start, deleteCount)
If you then want to "flatten" the results you can add .flat() or .flatMap() to the end (depending on your logic)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
If you know that you just want to grab the first item on each sub-array, you can:
topArray.map(subArray => subArray[0])
I would personnaly recommand using map which here takes for each element in your array, the second element (which is your object)
const arr = [
["2021-07-06T00:00:00Z", {type:"meeting",id:"123"}],
["2021-08-06T00:00:00Z", {type: "call", id: "456"}],
["2021-09-06T00:00:00Z", {type: "zoom", id: "789"}]
];
console.log(arr.map(item => item[1]))
Here's how you can do it:
let result = [];
let arr = [
["2021-07-06T00:00:00Z", {type:"meeting",id:"123"}],
["2021-07-06T00:00:00Z", {type: "call", id: "456"}]
];
result = arr.map((item)=>{
return item[1];
})
console.log(result);
You can use a slice to remove the first element of each subarray. And a flatMap to join all the filtered subarrays into one single array.
Here's how I would do it:
const filteredArray = array.flatMap((subarray) => subarray.slice(1));
use Map with filter
var a = [[1,2], [3,4]]
console.log(a.map((b) => b.filter((c, i) => i != 0)))
Result
[[2], [4]]
Related
So I have a series of objects that are pulled from an API and inputted into an array, something like such:
array = [
{id: 0, name: "First", relationship: "Friend"},
{id: 1, name: "Second", relationship: "Friend"}
]
The user is allowed to add and remove objects to the list freely (they will appear within a Vue.JS DataTable), and said user is allowed a maximum of 4 objects within the array (lets say 4 "friends")
How should I go about implementing a function that searches the existing array (say, if its populated from the API), and inputs the new object with the corresponding ID that is missing (so if the user deletes the object with the id 2, and adds another, it will search said array with objects, find the missing id 2 slot in the array, and input the object in its place)?
Previously I have gone about it via implement array.find() with conditionals to see if the array contains or does not contain the certain id value, however, it searches through each entry and can end up inserting the same object multiple times. Another method I haven't attempted yet would be having a separate map that contains ids, and then when a user removes an object, having it correspond with the map, and vice versa when adding.
Any suggestions? Thanks
Instead of an array, I'd keep an object in data. Have it keyed by id, like this:
let objects = {
0: { id: 0, name: 'name0', relationship: 'relationship0' },
1: { id: 1, name: 'name1', relationship: 'relationship1' },
}
Integer keys in modern JS will preserve insertion order, so you can think of this object as ordered. The API probably returns an array, so do this...
// in the method that fetches from the api
let arrayFromApi = [...];
this.objects = array.reduce((acc, obj) => {
acc[obj.id] = obj; // insertion order will be preserved
return acc;
}, {});
Your UI probably wants an array, so do this (refer to "array" in the markup):
computed: {
array() {
return Object.values(this.objects);
},
To create a new object, insert it in order, minding the available keys. Note this is a linear search, but with small numbers of objects this will be plenty fast
methods: {
// assumes maxId is const like 4 (or 40, but maybe not 400)
createObject(name, relationship) {
let object = { name, relationship };
for (let i=0; i< maxId; i++) {
if (!this.objects[i]) {
object.id = i;
this.objects[i] = object;
break;
}
}
try this,
let array = [
{id: 0, name: "First", relationship: "Friend"},
{id: 4, name: "Second", relationship: "Friend"},
{id: 2, name: "Second", relationship: "Friend"},
]
const addItem = (item) => {
let prevId = -1
// this is unnecessary if your array is already sorted by id.
// in this example array ids are not sorted. e.g. 0, 4, 2
array.sort((a, b) => a.id - b.id)
//
array.forEach(ob => {
if(ob.id === prevId + 1) prevId++
else return;
})
item = {...item, id: prevId + 1 }
array.splice(prevId+1, 0, item)
}
addItem({name: "x", relationship: "y"})
addItem({name: "a", relationship: "b"})
addItem({name: "c", relationship: "d"})
console.log(array)
You can simply achieve this with the help of Array.find() method along with the Array.indexOf() and Array.splice().
Live Demo :
// Input array of objects (coming from API) and suppose user deleted 2nd id object from the array.
const arr = [
{id: 0, name: "First", relationship: "Friend" },
{id: 1, name: "Second", relationship: "Friend" },
{id: 3, name: "Fourth", relationship: "Friend" }
];
// find the objects next to missing object.
const res = arr.find((obj, index) => obj.id !== index);
// find the index where we have to input the new object.
const index = arr.indexOf(res);
// New object user want to insert
const newObj = {
id: index,
name: "Third",
relationship: "Friend"
}
// Insert the new object into an array at the missing position.
arr.splice(index, 0, newObj);
// Output
console.log(arr);
Right now I need to merge the string into one.
This is my try ->
After this merge i got example of array ->
[
[{id: 1, name: "One"}],
[{id: 2, name : "two"}]
]
problem is newData because always print new array.
I need to data be like ->
[
{id: 1, name: "One"},
{id: 2, name : "two"}
]
What i am try, with foreEach ->
newState((oldData) => [...oldData, newData.forEach((new) => new)]);
No work.
Also what I am try
let filteredArray = newData.map(data => data);
Also no work, why?
Every time I get new information inside array newData....
I need solution to get only result inside array and print to
newState((oldData) => [...oldData, newResultWhichIsObject]);
Also some time my newData have few object inside array
The map method isn't the right method to use in your case. Map method will take as an entry an array of n elements and mutate it into an array of n element, on which an operation was applied. See MDN documentation
You should use the reduce method, which provides the ability to construct a brand new array from an empty one, here is the snippet :
const baseArray = [
[{id: 1, name: "One"}],
[{id: 2, name : "two"}]
];
const flattenedArray = baseArray.reduce((acc, curr) => ([...acc, ...curr]), []);
// For demo purpose, console.log
console.log(flattenedArray);
Reduce array method is a bit tricky, that is why I invite you to read the documentation carefully and play with it.
You can use .flat() method. Try this
const newData = [
[{id: 1, name: "One"}],
[{id: 2, name : "two"}]
];
console.log(newData.flat())
I wanted to add a key:value parameter to all the objects in an array from another array
eg:
var arrOfObj = [{id: 001, date:'22/05/2020', Actor:'jane'},
{id: 002, date:'02/03/2020', Actor:'alice'},
{id: 003, date:'11/06/2020', Actor:'jean'},
{id: 004, date:'20/01/2020', Actor:'yann'}];
var arrayScore = [44,2,3,5];
I want add for every objects a key:value parameter from arrayScore, like :
var arrOfObj = [{id: 001, date:'22/05/2020', Actor:'jane', score:44},
{id: 002, date:'02/03/2020', Actor:'alice', score:2},
{id: 003, date:'11/06/2020', Actor:'jean', score:3},
{id: 004, date:'20/01/2020', Actor:'yann', score:5}];
I tried this code:
var result = arrOfObj.map(function(el) {
var o = Object.assign({}, el);
o.score = arrayScore;
return o;
});
console.log(result);
but arrOfObj add all values from arrayScore for every object!!
How can I change this please??
Thank you for your HELP!
You can use Array.map to create the new array including the user scores, I would also take note of TJCrowders's point about the Ids.
var arrOfObj = [{id: 1, date:'22/05/2020', Actor:'jane'},
{id: 2, date:'02/03/2020', Actor:'alice'},
{id: 3, date:'11/06/2020', Actor:'jean'},
{id: 4, date:'20/01/2020', Actor:'yann'}];
var arrayScore = [44,2,3,5];
const result = arrOfObj.map((el, index) => ({...el, score: arrayScore[index] }));
console.log("Result with scores:", result);
Since you do not need a new array of objects, but only need to add the properties to the objects in the array, you can use the array method forEach instead of map.
If we pass two parameters to the callback provided to forEach, the second parameter will receive the index of the array element we are iterating over. This allows us to assign the corresponding value from the arrayScore array.
This should work
arrOfObj.forEach((o, i) => {
o.score = arrayScore[i];
});
Cheers!
This question already has answers here:
Find object by id in an array of JavaScript objects
(36 answers)
Closed 4 years ago.
I have an array of json objects:
[ {id:0, name:'A'}, {id:1, name:'B'}...{id:n, name:'N'} ]
How do i get the value (name) base on a given id, without iterating the array? Perhaps using map or some filter method...
const arr = [ {id:0, name:'A'}, {id:1, name:'B'},{id:3, name:'N'} ];
const inputId = 1;
const foundObj = arr.find(({ id }) => id === inputId);
if (foundObj) console.log(foundObj.name);
This still does iterate the array internally, though (as any method will).
This find method will find object based on your object property and value.
ArrayName.find(x => x.id === 0);
let array = [ {id:0, name:'A'}, {id:1, name:'B'}, {id:'n', name:'N'} ]
//To search in array we must iterate. But if you want to optimise performance for multiple searches you can map it to object by id.
let map = array.reduce((acc,element)=>{acc[element.id]=element;return acc;},{})
console.log(map[0])
console.log(map[1])
console.log(map.n) //As n was used as id.
Maps take one iteration to construct. Value retrieval thereon is sublinear.
// Input.
const input = [{id: 0, name:'A'}, {id: 1, name:'B'}, {id: 13, name:'N'}]
// To Map.
const toMap = (A) => new Map(A.map(x => [x.id, x]))
// Output.
const output = toMap(input)
// Proof.
console.log(output.get(0))
console.log(output.get(1))
console.log(output.get(13))
When you want to find an element in a collection, array might not be the best choice, objects or maps are much better in that case.
Each time you have to find an element, you would have to iterate over the array which would take O(n) time.
To avoid this, you could have an API layer in the middle, to convert your array into an a data structure which maps values by unique keys. You could achieve this by a plain Javascript Object.
That way you could find your element by id in O(1) without any iteration.
//original data
let arr = [ {id:0, name:'A'}, {id:1, name:'B'}, {id:2, name:'N'} ];
//convert it into object
let obj = arr.reduce((acc, curr) => {
acc[curr.id] = curr;
return acc;
}, {});
//modified data
{ 0: { id: 0, name: 'A' },
1: { id: 1, name: 'B' },
2: { id: 2, name: 'N' } }
//Now, you can look up value on any id as
obj[id].name;
For an array I can do:
array.push(array.shift())
var array = [0, 1, 2, 3, 4, 5];
array.push(array.shift())
console.log(array); // [1, 2, 3, 4, 5, 0]
How can I do the same for an object?
Input
var object = {0: 'Fiat', 1: 'Audi', 2: 'BMW', 3: 'Citroën'}
How can I move {0: 'Fiat'} to the end of the object
Expected output:
{0: 'Audi', 1: 'BMW', 2: 'Citroën', 3: 'Fiat'}
You can use the following way
var object = {0: 'Fiat', 1: 'Audi', 2: 'BMW', 3: 'Citroën'};
var result = Object.keys(object).map(e => object[e]);
//console.log(result);
result.push(result.shift());
//console.log(result);
let ans = Object.assign({}, result);
console.log(ans);
You could convert you object with the given keys as index to an array, apply the shifting and convert back to an object.
var object = { 0: 'Fiat', 1: 'Audi', 4: 'BMW', 5: 'Citroën' },
array = Object.keys(object).reduce((r, k, i) => (r[i] = object[k], r), []);
array.push(array.shift());
console.log(Object.assign({}, array)); // { 0: "Audi", 1: "BMW", 2: "Citroën", 3: "Fiat" }
A different approach, while respecting the keys.
var object = { 0: 'Fiat', 1: 'Audi', 4: 'BMW', 5: 'Citroën' },
keys = Object.keys(object);
result = Object.assign(...keys.map((k, i) => ({ [k]: object[keys[(i + 1) % keys.length]] })));
console.log(result); // { 0: "Audi", 1: "BMW", 4: "Citroën", 5: "Fiat" }
The object's properties does not have any guarantee on the order, in which they may appear, concise there is no concept as order. I think you need to think more and can find another solution, which does not depend on the properties order.
You can convert your object into an array, do the reordering on the array and convert the array back to an object:
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
rv[i] = arr[i];
return rv;
}
function toArray(object) {
return Object.keys(object).map(function (key) { return object[key]; });
}
var object = {0: 'Fiat', 1: 'Audi', 2: 'BMW', 3: 'Citroën'}
var array = toArray(object);
array.push(array.shift());
object = toObject(array);
console.log(object);
You should not rely on ordering of object's keys in JavaScript. It's not defined by standard. Objects by definition do not have an ordering, so there is no "end" of the object. It simply doesn't make sense to "move" a key of an object anywhere, since there's no ordering.
The data-structure which does have orders are arrays.
Your object is almost array-like, because all of its keys are consecutive numbers, but it's missing a lenght property. With length, you could turn it into an actual array with Array.from(object).
As Suren said, the object does not guarantee the insertion order. I suggest another approach for example:
const o = {0: 'Fiat', 1: 'Audi', 2: 'BMW', 3: 'Citroën'};
const k = Object.keys(o);
k.push(k.shift());
const result = k.map((v, i) => ({[i]: o[v]}))
.reduce((acum, v) => Object.assign(acum, v), {});
The approach here is to create and index array, apply the logic (push and shift) then re-build the object with map, and then merge them into one object with reduce. I think this could be shorter (just the reduce) but i wanted to split this up to be more clear.
Teaching: Objects are usually based on a Hash table for lookup by key.
As a consequence this usually means you do not have order.
myObj[key] => find value by computing hash of key => returns value