Move an item of an array to the front - javascript

I need to move a selected item in an array to the start of the array. Lets say I have an array of 5 items
[{"A", "B", "C", "D", "E"}].
Now, say I choose index 2 (which will be C) and I need to move C (index 2) to the start of the Array. Finally the array should display as follows:
[{"C", "A", "B", "D", "E"}].

Solution: You can solve your problem by using nested Array.Splice() methods. I would make this an extension method on arrays.
Array.prototype.move = function(from, to) {
this.splice(to, 0, this.splice(from, 1)[0]);
};
Explanation: The inner splice() is essentially saying take the item you are wanting to move, remove it from the array, and use the value of that item in the outer splice(). The outer splice() is saying to insert the item you just removed from the array at the index you specified in to.
Array.prototype.move is Javascript's way of creating an extension method called move on array objects. Any code that has access to this function can call move(from, to) on any array (e.g. myArray.move(2, 0)). So I would put this somewhere global so all your code can see it!
Example:
var letters = ["A", "B", "C", "D", "E"];
letters.move(2, 0);
// letters is now ["C", "A", "B", "D", "E"]

Here an example, how to do it:
<script>
var people = [
{name: 'Collin', city: 'Omaha', friend: false},
{name: 'Alice', city: 'New York', friend: false},
{name: 'Pasha', city: 'Moscow', friend: true},
{name: 'Denis', city: 'St. Pete', friend: true}
];
function toBeginning(index)
{
var obj = people[index];
people.splice(index, 1);
people.unshift(obj);
}
// To test it
alert(people[0].name); // Alert: Collin
toBeginning(2); // move position 2 (Pasha) to Beginning
alert(people[0].name); // Alert: Pasha

Related

How to sort a key value pair of array in javascript

So I have this array getting fetched from firebase and I have been trying to map that array and the array is in key value pair
{
A: {name: "test1", views: "20"},
B: {name: "test2", views: "30"},
C: {name: "test3", views: "23"}
}
I want to either map them or if I can reverse this array like
{ C: {}, B: {}, A: {}}
I'm doing all this in react native so please suggest some solution to it.
If you want to just sort it alphabetically.
const unsorted = {
A: {name: "test1", views: "20"},
B: {name: "test2", views: "30"},
C: {name: "test3", views: "23"}
}
const sorted = {};
Object.keys(unsorted).sort().forEach(key => {
sorted[key] = unsorted[key];
});
or reverse alphabetically sorted one.
Object.keys(unsorted).sort().reverse().forEach(key => {
sorted[key] = unsorted[key];
});
So i was searching the web and found this
As above you guys suggested it is not an array it is an Object and can be sorted this way
let list = Object.entries(snapshot.val())
.sort(function (x, y) {
return x[1].spectators - y[1].spectators;
})
.reverse();
this is for descending order for ascending remove reverse()
Thank you!
Reversing the sequence in which keys are extracted from an object is a bit annoying because you have to take them all out and then place them back all in in the order you want:
function reverse(o) {
let entries = Object.entries(o).reverse();
entries.forEach(e => delete o[e[0]]);
entries.forEach(e => o[e[0]] = e[1]);
}
This code works by mutating the object, thus maintaining eventually references from other objects to this one valid; mutating the object is also important to maintain the correct prototype of the object if it wasn't the default. If you want to clone it instead you should be careful about copying the same prototype.

Immutable.js mergeDeepWith issue

I amusing Immutable.js and having problems merging an object with an array .
My fucntion for merging is:
function singleTrackReducer(state = Immutable.Map(singleTrack), action) {
switch (action.type){
case AudioFormActions.CHANGE:
return state.mergeDeepWith((prev, next) => next, action.entity);
default:
return state;
}
}
The object that I am merging to looks like this:
const singleTrack = {
songTitle: '',
mainArtists: [],
featuredArtists: [],
releaseDate: '',
primaryGenre: '',
isExplicit: false,
labelName:'',
upCode: '',
eanCode: '',
isrcCode:'',
copyRight: ''
};
I am trying to update the mainArtists property.. For example i can add several artists to my artist array and perform an update successfully. However when I delete an object from the array it appears to be filled with a previous object.
Say for example the artist Array is [drake, rihanna, tyga]
If I call the function with action entity [drake, rihanna, tyga, john] it updates fine and the mainArtists property becomes [drake, rihanna, tyga, john].
when I delete an artist example tyga and the array is [drake, rihanna, john]
the mainArtist property becomes [drake, rihanna, john, john]
Can anyone explain how I can resolve this issue
I think this code will help you understand the issue:
var Immutable = require('immutable');
console.log(
Immutable.List(['a', 'b', 'c'])
.mergeDeep(['a', 'c'])
);
// output: List [ "a", "c", "c" ]
console.log(Immutable.List(['a', 'b', 'c'])
.mergeDeepWith((prev, next) => {
console.log(`Conflict between ${prev} and ${next}.`);
return next;
}, ['a', 'c'])
);
// output: Conflict between a and a.
// Conflict between b and c.
// List [ "a", "c", "c" ]
Basically, when merging lists, items appear to be copied from one to the other at each index, and if there's already a value at that index, it's considered a conflict:
For index #0, there's "a" in the first list and "a" in the second list. We resolve the conflict by preferring the second value (though in this case they're identical). So index #0 gets "a".
Then we go to index #1 and find the first list has "b" and the second list has "c". We resolve the conflict by choosing the second value, so index #1 gets "c".
Now for index #2, we have no conflict, since only the first list has a value. We keep "c" in index #2, so the final list is "a", "c", "c".
You could instead use a set, but that basically performs a union operation, so nothing would ever be deleted:
console.log(
Immutable.Set(['a', 'b', 'c'])
.mergeDeep(['a', 'c'])
);
// output: Set { "a", "b", "c" }
I don't actually think you're looking to do a merge of this list at all... I think you simply want to copy the new value over the old value. If that's the case, maybe you're just looking for merge instead of mergeDeep:
var state = Immutable.Map({
songTitle: '',
mainArtists: [],
featuredArtists: [],
releaseDate: '',
primaryGenre: '',
isExplicit: false,
labelName:'',
upCode: '',
eanCode: '',
isrcCode:'',
copyRight: ''
});
function doMerge(state, newState) {
// no deep merge here, just copy whatever fields are present in newState
return state.merge(newState);
}
console.log(state.get('mainArtists'));
// output: []
state = doMerge(state, {
mainArtists: ['drake', 'rihanna', 'tyga']
});
console.log(state.get('mainArtists'));
// output: List [ "drake", "rihanna", "tyga" ]
state = doMerge(state, {
mainArtists: ['drake', 'rihanna', 'tyga', 'john']
});
console.log(state.get('mainArtists'));
// output: List [ "drake", "rihanna", "tyga", "john" ]
state = doMerge(state, {
mainArtists: ['drake', 'rihanna', 'john']
});
console.log(state.get('mainArtists'));
// output: List [ "drake", "rihanna", "john" ]

JavaScript - Check if one array has the same index from a second array

Let's say I have an object of
var people = [
{name: 'John'}, // 0
{name: 'James'}, // 1
{name: 'Sue'}, // 2
{name: 'Mary'}, // 3
{name: 'Will'}, // 4
{name: 'Lukas'}, // 5
{name: 'Sam'} // 6
];
and then I have this array: var history = [0, 2, 4, 6]; // we have John, Sue, Will and Sam
Using Lodash, or general JavaScript, how can I make it to return true or false if a entered value is found inside the history[] array.
For example, isInHistoryArray(5) would return false but isInHistoryArray(2) would return true
For example
You have list-array of players in the small game:
var people = [
{name: 'John'},
{name: 'James'},
{name: 'Sue'},
{name: 'Mary'},
{name: 'Will'},
{name: 'Lukas'},
{name: 'Sam'}
];
And you have array of the... actually connected people:
var history = [0, 2, 4, 6];
Okay, lets say that both containers are in the global scope for comfort.
You can check it by this function body
function checkHistory(a){
for(var i = 0; i < history.length; i++){
if(history[i] === a) return true;
}return false;}
You can just use `includes' method
history.includes(5) // false
history.includes(0) // true
Arrays have an indexOf method that compares what you give it against the entries in the array (using strict comparison, ===) and tells you the index of the first match, or -1 (specifically) if there is no match. So:
function isInHistoryArray(value) {
return history.indexOf(value) !== -1;
}
In ES2015, there are also Array.find and Array.findIndex (both of which can be polyfilled on older engines) that let you supply a predicate callback, but you don't need that here as your entries are numbers and what you're checking is also a number.

Looping an array within an object and manipulating the object data based on array values?

I have this really painful task which i would like to share it with more experienced developers. It seems easy but i think it's really tricky. I will just show you the object here because the real one has a lot of other things involved.
This is the object:
var data = {
checkboxes: ["A", "B", "C"],
customers : 1,
expDate: 2015
}
if i do a simple for loop based on data.checkboxes.length i end up with this:
Object {checkboxes: Array["A", "B", "C"], customers: 1, expDate: 2015}
Object {checkboxes: Array["A", "B", "C"], customers: 1, expDate: 2015}
Object {checkboxes: Array["A", "B", "C"], customers: 1, expDate: 2015}
as you can see each checkboxes contains 3 items, this is not something that i want. I want each object to have one value from the checkboxes array.
Here is the result i expect to get:
Object {checkboxes: "A", customers: 1, expDate: 2015}
Object {checkboxes: "B", customers: 1, expDate: 2015}
Object {checkboxes: "C", customers: 1, expDate: 2015}
I don't know but to me it seems very confusing. Maybe you guys have already done similar thing before. I will much appreciate it if you share your thoughts.
Thanks in advance
You need to use that iterator to access sub-index of checkboxes
var data = {
checkboxes: ["A", "B", "C"],
customers : 1,
expDate: 2015
}
console.log(data);
function getFormattedData()
{
document.write("<p>Printing Results:<br/>");
var results = [];
for(var i = 0; i < data.checkboxes.length; i++)
{
results[i] = data.checkboxes[i] + ", " + data.customers + ", " + data.expDate;
document.write(results[i] + "<br/>");
}
document.write("</p>");
return results;
}
getFormattedData();
data.customers = 2;
getFormattedData();
EDIT: made into resusable functions, following comment when questioner
I'm not sure if it is what you want but try out this code.
var data = {
checkboxes: ["A", "B", "C"],
customers : 1,
expDate: 2015
}
var result = data.checkboxes.map(function(s) {
return {
checkboxes: s,
customers : data.customers,
expDate: data.expDate
};
});

How can I iterate through an object array and add matching values while pushing new values

So I have two data sets. The mainData being the data I want to push to and display as the main data set.
// data set 1
var mainData = [{name: "david", views: 2}, {name: "andrew", views: 2}];
// data set 2
var newData = [{name: "andrew", views: 4}, {name: "david", views: 4}, {name: "chris", views: 2}];
The second data set is new or incoming data which I want to do one of two things with. I want to search through the main data set and see if any keys match, if so I just want to add views to the object with the same name. If the name key doesn't match any object in the mainData I want to then push that object to mainData.
My final mainData should look like this:
[{name: "david", views: 6}, {name: "andrew", views: 6}, {name: "chris", views: 2}]
Notice how david and andrew now have values of 6 while chris did not match any objects and was simply pushed. What is the most effiecient way of acheiving this in pure Javascript?
If you want to empty newData during processing do:
while (newData.length) {
var nd = newData.shift(), nam = nd.name, vie = nd.view;
if (!mainData.some(function(md) {
if (md.name === nam) {md.view += vie; return true;}
})) mainData.push(nd);
}
else if the objects in newData shall stay there do
newData.forEach(function(nd) {
var nam = nd.nam, vie = nd.view;
if (!mainData.some(function(md) {
if (md.name === nam) {md.view += vie; return true;}
})) mainData.push(nd);
});
In both cases mainData.some() iterates over mainData. Its callback function checks at each step whether the name-properties are identic. If so, the view-properties are added, the callback returns true (= "matching names found") and iteration is stopped. Otherwise the callback returns nothing and iteration goes on. Since some() is inside an negated condition, mainData.push() happens only if some() does not find a match.
Array.forEach() and some() are very fast. If they are not available, you have to use for-loops with less efficiency.

Categories